【发布时间】:2021-02-03 12:50:35
【问题描述】:
我是 Redux 的新手。我正在使用 Reactjs、Redux 和 React-flow 制作一个可视化工作流平台。用户可以通过在 Palette 中输入节点名称和类型来添加节点(如图所示右侧)。我将新节点名称及其类型传递给 Redux dispatch 。调度和更新状态工作正常(我已经通过在控制台上打印它来检查它),状态正在更新,但我没有自动获取更新的状态,就像每当我们在 Reactjs 中更新一个钩子时,它的更改都会显示在使用钩子变量的任何地方.但在这里它不是那样工作的。我在中间 div 的顶部打印更新后的状态长度(显示节点),即使我向状态添加新对象,它也只显示 0。
我在网上搜索了一下,发现 Redux 中的 Connect 功能会有所帮助,我也实现了它。但没有解决办法。
过去 2 天我一直在寻找它,但无法弄清楚问题出在哪里。 如果有人知道问题出在哪里,我缺少/忽略了什么。请告诉我,这将是很大的帮助。
Graph.js(我希望状态自动更新):
import React, { useState, useEffect } from 'react';
import ReactFlow, { Controls, updateEdge, addEdge } from 'react-flow-renderer';
import { useSelector ,connect} from 'react-redux';
import input from '../actions/input';
const initialElements = [
{
id: '1',
type: 'input',
data: { label: 'Node A' },
position: { x: 250, y: 0 },
}]
function Graphs(props) {
const onLoad = (reactFlowInstance) => reactFlowInstance.fitView();
const [elements, setElements] = useState(initialElements);
// const [state,setState]=useState(useSelector(state => state.nodeReducers))
useEffect(() => {
if (props.elements.length) {
console.log("useEffect in", props.elements)
setElements(els => els.push({
id: (els.length + 1).toString(),
type: 'input',
data: props.elements.data,
position: props.elements.position
}));
return;
}
console.log("outside if ",props.elements)
}, [props.elements.length])
const onEdgeUpdate = (oldEdge, newConnection) =>
setElements((els) => updateEdge(oldEdge, newConnection, els));
const onConnect = (params) => setElements((els) => addEdge(params, els));
return (
<ReactFlow
elements={elements}
onLoad={onLoad}
snapToGrid
onEdgeUpdate={onEdgeUpdate}
onConnect={onConnect}
>
{console.log("in main", props.elements)}
<Controls />
<p>hello props {props.elements.length}</p>
</ReactFlow>
)
}
const mapStateToProps=state=>{
return{
elements:state.nodeReducers
}
}
const mapDisptachToProps=dispatch=>{
return{
nodedispatch:()=>dispatch(input())
}
}
export default connect(mapStateToProps,mapDisptachToProps)(Graphs);
nodeReducers.js(减速器):
const nodeReducers=(state=[],action)=>{
switch (action.type) {
case "ADD":
state.push(...state,action.NodeData)
console.log("in node reducers",state)
return state;
default:
return state;
}
}
export default nodeReducers;
input.js(动作):
const input = (obj = {}) => {
console.log("in action",obj)
return {
type: "ADD",
NodeData: {
type: 'input',
data: { label: obj.NodeValue },
position: { x: 250, y: 0 }
}
}
}
export default input;
PaletteDiv.js(我接受用户输入的右侧调色板 div):
import React, { useState } from 'react'
import '../styles/compoStyles/PaletteDiv.css';
import { makeStyles } from '@material-ui/core/styles';
import { FormControl, TextField, InputLabel, Select, MenuItem, Button } from '@material-ui/core';
import { connect } from 'react-redux';
import input from '../actions/input';
function PaletteDiv(props) {
const [nodename, setNodename] = useState();
const [nodetype, setNodetype] = useState();
const [nodevalue, setNodevalue] = React.useState('');
const handleChange = (event) => {
setNodevalue(event.target.value);
setNodetype(event.target.value);
};
const useStyles = makeStyles((theme) => ({
margin: {
margin: theme.spacing(1),
width: "88%"
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
}
}));
const styles = {
saveb: {
float: "left",
margin: "auto"
},
cancelb: {
float: "right"
},
inputfield: {
display: "block",
width: "100%",
margin: "0"
}
}
const classes = useStyles();
const useStyle = makeStyles(styles);
const css = useStyle();
return (
<div id="myPaletteDiv">
<div className="heading">
<h1>Palette</h1>
</div>
<div className="palette">
<label >WorkFlow Name</label>
<TextField id="outlined-basic" fullwidth className={css.inputfield} variant="outlined" onChange={e => setNodename(e.target.value)} />
<label >Type of Node</label>
<FormControl variant="outlined" className={classes.formControl}>
<InputLabel id="demo-simple-select-outlined-label">Node</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={nodevalue}
onChange={handleChange}
label="Age"
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Step</MenuItem>
<MenuItem value={20}>Condition</MenuItem>
</Select>
<Button variant="contained" color="primary" onClick={(e) => {
e.preventDefault();
const node = {
NodeType: nodetype,
NodeValue: nodename
}
props.nodedispatch(node)
console.log("done dispatching")
}}>
Add Node
</Button>
</FormControl>
</div>
</div>
)
}
const mapStateToProps = state => {
return {
elements: state.nodeReducers
}
}
const mapDisptachToProps = dispatch => {
return {
nodedispatch: (node) => dispatch(input(node))
}
}
export default connect(mapStateToProps, mapDisptachToProps)(PaletteDiv);
在这里你可以看到我有一个
标签在中间 div 的顶部。它显示“你好道具 0”。我希望在添加节点时更改 0(零)。
谢谢你
真诚的,
Rishabh Raghwendra
【问题讨论】:
-
你能在你
nodeReducer'ADD' 的情况下尝试return [...state, action.NodeData];吗? -
@SreekarMouli 我已经在我的代码中应用了你的方式,但是在显示更新状态后,应用程序突然崩溃了。我不知道问题出在哪里。我在上面添加了 PaletteDiv.js,用于将数据输入到 Redux 存储中。请看,是否有任何错误或我留下的东西?
标签: javascript reactjs redux