Reactjs 将对象链接到react-flow渲染器中的元素/redux存储中的react-flow
我一直在尝试将存储连接到我现有的工具包,Reactjs 将对象链接到react-flow渲染器中的元素/redux存储中的react-flow,reactjs,react-redux,redux-toolkit,Reactjs,React Redux,Redux Toolkit,我一直在尝试将存储连接到我现有的工具包,useStoreState充当useSelector我不确定它是否适合我的用例。 我想知道是否有一种方法可以将商店直接连接到我现有的redux toolkit商店,或者我是否必须始终将它分派到商店 function EditorReactFlow() { const classes = useStyles(); const reactFlowWrapper = useRef(null); const [reactFlowInstance, se
useStoreState
充当useSelector
我不确定它是否适合我的用例。
我想知道是否有一种方法可以将商店直接连接到我现有的redux toolkit商店,或者我是否必须始终将它分派到商店
function EditorReactFlow() {
const classes = useStyles();
const reactFlowWrapper = useRef(null);
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [elements, setElements] = useState(initialElements);
const [name, setName] = useState("")
const dispatch = useDispatch();
useEffect(() =>{
dispatch(addStep(elements))
},[dispatch, elements])
const onConnect = (params) => setElements((els) => addEdge(params, els));
const onElementsRemove = (elementsToRemove) =>
setElements((els) => removeElements(elementsToRemove, els));
const onLoad = (_reactFlowInstance) =>{
_reactFlowInstance.fitView();
setReactFlowInstance(_reactFlowInstance);}
const addNode = () => {
setElements(e => e.concat({
id: getId(),
data: {label: `${name}`},
position: {x: 0, y: -5},
},
))
};
return (
<Container maxWidth="lg">
<CssBaseline />
<div className={classes.paper}> </div>
<div className="{classes.heroContent} reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
style={{width:'100%',height: '90vh'}}
onLoad={onLoad}
onConnect = {onConnect}
>
<Controls />
</ReactFlow>
<input type="text"
onChange={e => setName(e.target.value)}
name="title"/>
<button
type="button"
onClick={addNode}
>Add Node</button>
</div>
<RfEditorSidebar />
</Container>
);
}
export default connect(
(state) => ({ todos: state})
)(EditorReactFlow);
我当前的问题是,我试图将活动元素放入我的存储中,并使每个对象链接到另一个项目,但是由于useStoreState
返回整个对象,因此当我dispatch
将其发送到存储中时,它将变成不可序列化的。这意味着,无论何时删除/添加元素,它都会刷新redux toolkit存储中的存储状态,这反过来会使用新对象更新存储,但所有链接的对象都会失去与该元素的连接并被删除
我所在州的示例:
[{elementID: 1, linkedText: "bla bla"}, {elementID: 2, linkedText: "bla bla for 2"}, {elementID: 3}]
当我添加/删除一个元素时,比如说元素3,它会将状态重置为
[{elementID: 1}, {elementID: 2}]
哪个选项会删除所有存储的链接文本
这附近有什么我可以看的工作吗?也许能够以某种方式将结果直接存储到现有的redux toolkit存储中?我知道使用了easy peasy,我试着研究如何将它连接到商店,但我也没能实现
export default connect((state) => ({ elements: state}))(EditorReactFlow);
我还应该在redux开发工具中看到react-flow渲染器的内部存储吗?我只能看到我自己的应用程序,所以我想不会吧
编辑:
目前我分派的是来自实际react流渲染器的元素,下面我已经发布了组件。在useffect
上,元素被分派到我的redux切片中的addStep()
,该切片将解构它以获取ID并将其存储在存储中
function EditorReactFlow() {
const classes = useStyles();
const reactFlowWrapper = useRef(null);
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [elements, setElements] = useState(initialElements);
const [name, setName] = useState("")
const dispatch = useDispatch();
useEffect(() =>{
dispatch(addStep(elements))
},[dispatch, elements])
const onConnect = (params) => setElements((els) => addEdge(params, els));
const onElementsRemove = (elementsToRemove) =>
setElements((els) => removeElements(elementsToRemove, els));
const onLoad = (_reactFlowInstance) =>{
_reactFlowInstance.fitView();
setReactFlowInstance(_reactFlowInstance);}
const addNode = () => {
setElements(e => e.concat({
id: getId(),
data: {label: `${name}`},
position: {x: 0, y: -5},
},
))
};
return (
<Container maxWidth="lg">
<CssBaseline />
<div className={classes.paper}> </div>
<div className="{classes.heroContent} reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
style={{width:'100%',height: '90vh'}}
onLoad={onLoad}
onConnect = {onConnect}
>
<Controls />
</ReactFlow>
<input type="text"
onChange={e => setName(e.target.value)}
name="title"/>
<button
type="button"
onClick={addNode}
>Add Node</button>
</div>
<RfEditorSidebar />
</Container>
);
}
export default connect(
(state) => ({ todos: state})
)(EditorReactFlow);
EditorReactFlow
将“元素”存储为内部状态和redux的全局状态,这是有问题的
- 元素存储为
EditorReactFlow
组件的内部状态:const[Elements,setElements]=useState(initialElements)代码>
- 元素也用于
dispatch
调用以更新Redux的全局状态:dispatch(addStep(Elements))
- 这是有问题的,因为这两种状态都会尝试以各自的方式更新视图/反应组件,而且通常情况下,数据有两种不同的真实来源是不好的
通常,如果一个状态需要存储在Redux中,则通过Redux检索和更新它,而不使用useState
,这不是Redux的一部分
而不是<代码> UsStuts<代码>,请考虑通过以下方式映射ReDux状态:
- 移除
const[elements,setElements]=useState(initialElements)代码>
- 将函数签名从
function EditorReactFlow(){
更改为function EditorReactFlow(props){
- 使用
props.todos.data
- 删除对
useffect
的调用(请参阅下一项以了解解释)
- 直接调用
dispatch(addStep(…)/*可重复用于其他操作*/
作为任何回调函数的一部分,例如addNode
编辑:
最后,您的EditorReactFlow
应该是这样的:
function EditorReactFlow(props) {
const classes = useStyles();
const reactFlowWrapper = useRef(null);
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [name, setName] = useState("")
const dispatch = useDispatch();
let elements = props.todos.data; // Redux passes elements list through props
const onConnect = (params) => {
// Here, addEdge should be a Redux action, and needs to be dispatched
dispatch(addEdge(params, elements));
};
const onElementsRemove = (elementsToRemove) => {
// Here, removeElementsshould be a Redux action, and needs to be dispatched
dispatch(removeElements(elementsToRemove, elements));
};
const onLoad = (_reactFlowInstance) =>{
_reactFlowInstance.fitView();
setReactFlowInstance(_reactFlowInstance);}
const addNode = () => {
dispatch(addStep(elements.concat({
id: getId(),
data: {label: `${name}`},
position: {x: 0, y: -5},
}))
};
return (
<Container maxWidth="lg">
<CssBaseline />
<div className={classes.paper}> </div>
<div className="{classes.heroContent} reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
style={{width:'100%',height: '90vh'}}
onLoad={onLoad}
onConnect = {onConnect}
>
<Controls />
</ReactFlow>
<input type="text"
onChange={e => setName(e.target.value)}
name="title"/>
<button
type="button"
onClick={addNode}
>Add Node</button>
</div>
<RfEditorSidebar />
</Container>
);
}
export default connect(
// Ask Redux to pass Redux state to "props.todos"
// According to your "addStep" reducer, elements are stored as "state.data"
// So, elements list will be passed as "props.todo.data"
(state) => ({todos: state})
)(EditorReactFlow);
函数编辑器或reactflow(道具){
const classes=useStyles();
const reactFlowWrapper=useRef(null);
常量[reactFlowInstance,setReactFlowInstance]=useState(null);
const[name,setName]=useState(“”)
const dispatch=usedpatch();
let elements=props.todos.data;//Redux通过props传递元素列表
常量onConnect=(参数)=>{
//在这里,addEdge应该是一个Redux操作,并且需要被调度
调度(添加(参数、元素));
};
常量OneElementsRemove=(elementsToRemove)=>{
//在这里,RemoveElements应该是一个Redux操作,并且需要进行调度
分派(移除元素(元素StoreMove,元素));
};
const onLoad=(\u reactFlowInstance)=>{
_reactFlowInstance.fitView();
setReactFlowInstance(_reactFlowInstance);}
const addNode=()=>{
调度(addStep)(elements.concat({
id:getId(),
数据:{label:`${name}`},
位置:{x:0,y:-5},
}))
};
返回(
setName(e.target.value)}
name=“title”/>
添加节点
);
}
导出默认连接(
//要求Redux将Redux状态传递给“props.todos”
//根据“addStep”缩减器,元素存储为“state.data”
//所以,元素列表将作为“props.todo.data”传递
(state)=>({todos:state})
)(EditorReactFlow);
这可能会为您指明正确的方向。请让我知道这是否有帮助。您好,您可以分享您发送的操作的代码吗?如果没有其他信息,很难知道为什么状态会被这样覆盖。您好,感谢您的回复,我已经更新了代码,以显示完整的组件和所有还原器。是的,这一切都很有道理。谢谢,我想我现在肯定可以继续了。谢谢。我必须将它应用到大多数处理程序中,以便他们更新我自己的全局redux存储并从本质上使用它。
function EditorReactFlow(props) {
const classes = useStyles();
const reactFlowWrapper = useRef(null);
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [name, setName] = useState("")
const dispatch = useDispatch();
let elements = props.todos.data; // Redux passes elements list through props
const onConnect = (params) => {
// Here, addEdge should be a Redux action, and needs to be dispatched
dispatch(addEdge(params, elements));
};
const onElementsRemove = (elementsToRemove) => {
// Here, removeElementsshould be a Redux action, and needs to be dispatched
dispatch(removeElements(elementsToRemove, elements));
};
const onLoad = (_reactFlowInstance) =>{
_reactFlowInstance.fitView();
setReactFlowInstance(_reactFlowInstance);}
const addNode = () => {
dispatch(addStep(elements.concat({
id: getId(),
data: {label: `${name}`},
position: {x: 0, y: -5},
}))
};
return (
<Container maxWidth="lg">
<CssBaseline />
<div className={classes.paper}> </div>
<div className="{classes.heroContent} reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
style={{width:'100%',height: '90vh'}}
onLoad={onLoad}
onConnect = {onConnect}
>
<Controls />
</ReactFlow>
<input type="text"
onChange={e => setName(e.target.value)}
name="title"/>
<button
type="button"
onClick={addNode}
>Add Node</button>
</div>
<RfEditorSidebar />
</Container>
);
}
export default connect(
// Ask Redux to pass Redux state to "props.todos"
// According to your "addStep" reducer, elements are stored as "state.data"
// So, elements list will be passed as "props.todo.data"
(state) => ({todos: state})
)(EditorReactFlow);