折腾:
【未解决】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()
即可强制刷新。则字元素也就正常了。