折腾:
【未解决】AntD Pro中支持剧本剧本编写时拖动排序单个对话
期间,需要对于
class DragSortingTable extends 
React.Component
 {
  state = {
    data: [
    ]
  }
}
  DragableDialogTable = DragDropContext(HTML5Backend)(DragSortingTable)
render() {
                <this.DragableDialogTable />
}这种情况,想要在DragSortingTable的外部,去更新内部state的值
以实现可以在新增一行后,把新的列表的值,传递到可拖动去改变列表元素排序的内部
同时还需要,对于已经改变了排序的结果的值,在外部需要获取能
这样每次新增之前,才能用最新的被拖动排序后的列去新增
或许直接用props参数即可?
react js change state from outside
好像是用componentWillReceiveProps更合适
去试试
但是此处突然发现,此处还没发写成:
// DragableDialogTable = DragDropContext(HTML5Backend)(DragSortingTable)
DragableDialogTable = DragDropContext(HTML5Backend)(DragSortingTable itemList={demoItemList})因为此处只是class DragSortingTable的调用而不是元素:
<DragSortingTable />
的调用,没法这么传递props
那貌似只能去试试:
直接给class DragSortingTable添加函数了
但是貌似是class的instance的函数,也没法加static的函数啊?
这样就没法修改每个instance的内部的state了?
突然想到了:
还是直接把DragSortingTable合并到当前的业务逻辑中,就可以了。
但是发现好像也不对,还是由于是class,没法直接直接合并
否则自己没法render自己
自己试试,能否添加额外函数,实现state的list的同步
或者加上额外的外部的全局变量去实现数据的同步
现在问题变成了:如何更新component class内部的state
react js change component class state
另外看到此处的代码中的DragDropContext的定义:

/** * Wrap the root component of your application with DragDropContext decorator to set up React DnD. * This lets you specify the backend, and sets up the shared DnD state behind the scenes. * @param backendFactory The DnD backend factory * @param backendContext The backend context */ export declare function DragDropContext(backendFactory: BackendFactory, backendContext?: any): <TargetClass extends React.ComponentClass <any> | React.StatelessComponent<any>>(DecoratedComponent: TargetClass) => TargetClass & ContextComponent<any>;
感觉是:
或许此处可以避开DragDropContext
因为此处不是root的element
然后希望不用传递TargetClass的方式,而是直接调用component,这样就可以传递参数和获取instance的state了。
去看看
中,是否一定要使用这种方式去调用
是我们需要的:

找了一下,终于找到这个example的代码了:
-》
-》
-》
-》
去参考看看代码:
git clone https://github.com/react-dnd/react-dnd.git
然后出错:
➜  react-dnd git:(master) npm install && npm start
npm WARN deprecated istanbul-lib-hook@1.2.1: 1.2.0 should have been a major version bump
> fsevents@1.2.4 install /Users/crifan/dev/dev_src/ReactJS/react-dnd/node_modules/fsevents
> node install
[fsevents] Success: "/Users/crifan/dev/dev_src/ReactJS/react-dnd/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" already installed
Pass --update-binary to reinstall or --build-from-source to recompile
> husky@0.14.3 install /Users/crifan/dev/dev_src/ReactJS/react-dnd/node_modules/husky
> node ./bin/install.js
husky
setting up Git hooks
done
npm WARN prepublish-on-install As of npm@5, `prepublish` scripts are deprecated.
npm WARN prepublish-on-install Use `prepare` for build steps and `prepublishOnly` for upload-only.
npm WARN prepublish-on-install See the deprecation note in `npm help scripts` for more information.
> react-dnd-master@ prepublish /Users/crifan/dev/dev_src/ReactJS/react-dnd
> npm test
> react-dnd-master@ test /Users/crifan/dev/dev_src/ReactJS/react-dnd
> run-s lint build test_modules jest:cov
> react-dnd-master@ lint /Users/crifan/dev/dev_src/ReactJS/react-dnd
> tslint "packages/**/*.{ts,tsx}" -e "**/{lib,node_modules}/**"
internal/modules/cjs/loader.js:596
    throw err;
    ^
Error: Cannot find module 'typescript'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:594:15)
    at Function.Module._load (internal/modules/cjs/loader.js:520:25)
    at Module.require (internal/modules/cjs/loader.js:650:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/Users/crifan/dev/dev_src/ReactJS/react-dnd/node_modules/tslint/lib/linter.js:22:10)
    at Module._compile (internal/modules/cjs/loader.js:702:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
    at Module.load (internal/modules/cjs/loader.js:612:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
    at Function.Module._load (internal/modules/cjs/loader.js:543:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! react-dnd-master@ lint: `tslint "packages/**/*.{ts,tsx}" -e "**/{lib,node_modules}/**"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the react-dnd-master@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/crifan/.npm/_logs/2018-08-06T05_55_53_490Z-debug.log
ERROR: "lint" exited with 1.
npm ERR! Test failed.  See above for more details.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! react-dnd-master@ prepublish: `npm test`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the react-dnd-master@ prepublish script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/crifan/.npm/_logs/2018-08-06T05_55_53_594Z-debug.log重新试试
结果npm install出错
算了。
只是去看代码,不运行demo了。


看了demo代码,也不是很容易懂。
刚看懂一点,好像是:
Container
只要用了:
@DragDropContext(HTML5Backend)

后,就可以正常的被别人调用了:

<Container />
那此处也去试试是否可以这么用
@DragDropContext(HTML5Backend)
class DragSortingTable extends 
React.Component
 {
  ...
}
    render() {
        return (
              <DragSortingTable
                itemList={this.demoItemList}
              />真的可以。
-》那么接下来,就容易改变list,然后传入新的list了。
然后期间遇到:
【未解决】Reactjs中传入属性变化后componentWillReceiveProps不工作没有调用
折腾:
【未解决】Reactjs中如何在Component的外部改变和获取state状态值
期间,
已经用代码:
@DragDropContext(HTML5Backend)
class DragSortingTable extends 
React.Component
 {
  state = {
    itemList: [],
  }
  constructor(props){
    super(props)
    console.log("DragSortingTable constructor: props=", props)
    console.log("this.props.itemList=", this.props.itemList)
    this.state.itemList = this.props.itemList;
  }
  componentWillReceiveProps(nextProps){
    console.log("DragSortingTable componentWillReceiveProps: nextProps=", nextProps)
    console.log("this.props.itemList=", this.props.itemList)
    if (this.props.itemList) {
      this.setState({itemList: this.props.itemList})
      console.log("updated this.state.itemList=", this.state.itemList)
    }
  }
  components = {
    body: {
      row: DragableBodyRow,
    },
  }
  moveRow = (dragIndex, hoverIndex) => {
    const { itemList } = this.state;
    const dragRow = itemList[dragIndex];
    this.setState(
      update(this.state, {
        itemList: {
          $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
        },
      }),
    );
  }
  render() {
    console.log("DragSortingTable render: this.state.itemList=", this.state.itemList)
    return (
      <Table
        columns={columns}
        dataSource={this.state.itemList}
        components={
this.components
}
        onRow={(record, index) => ({
          index,
          moveRow: this.moveRow,
        })}
      />
    );
  }
}
@connect(({ loading, script, topic }) => ({
  submitting: loading.effects['script/submitRegularForm'],
  script,
  topic,
}))
@Form.create()
export default class ScriptCreate extends PureComponent {
  。。。
  handleAddDialog(){
    console.log("handleAddDialog")
    const curItemList = this.state.dialogList
    let newItemList = curItemList
    const curItemNum = curItemList.length
    const newItemNum = curItemNum + 1
    let newDialog = {
      key: `${newItemNum}`,
      speakerOrSong: `new speaker ${newItemNum}`,
      contentOrAddress: `new content ${newItemNum}`,
    }
    console.log("newDialog=", newDialog)
    newItemList.push(newDialog)
    console.log("newItemList=", newItemList)
    this.setState({ dialogList: newItemList})
    console.log("this.state.dialogList=", this.state.dialogList)
  }
    render() {
        return (
              <DragSortingTable
                itemList={this.state.dialogList}
              />实现了,当点击添加按钮时,去新增一行,且用
this.setState({ dialogList: newItemList})
更新了state,但是DragSortingTable中的componentWillReceiveProps却没运行
react  props changed componentWillReceiveProps not called
* if its not receiving a new props object from the redux store
猜测是此处用了redux而导致此处state变化了,但是componentWillReceiveProps也没有运行
如何解决呢?
想起来别人提起来的,强制刷新,试试:
this.forceUpdate()
就可以了。
【总结】
当reactjs使用了redux,则会导致setState后,子元素中的state变量变化了,但是子元素中的componentWillReceiveProps也不允许,从而无法实现刷新显示的效果
解决办法是,对于父元素中,setState后,加上:
this.forceUpdate()
即可强制刷新。则字元素也就正常了。