React js从父事件中更新子状态

Posted

技术标签:

【中文标题】React js从父事件中更新子状态【英文标题】:React js update child state from an event in the parent 【发布时间】:2020-06-16 21:57:35 【问题描述】:

我有一个向客户端提供数据的 WebSocket,并且我正在使用 D3 反应在图表中显示它(数据),所以我希望我的图表根据数据进行更改,但要更改图表组件,我必须从定义 onMessage 事件的父组件访问它,我的问题是图表没有更新:

父组件:

class App extends Component 
constructor(props) 
    super(props);
    this.state = 
      data: [],
    ;
  
  handleData(data) 
      let result = JSON.parse(data);
      this.setState((state) => 
        state.data.push(result.c.gas);
      );
  

  render() 
    return (
      <div>
        <Websocket
          url=`ws://$window.location.host/ws/mqtt_app/1/`
          onMessage=this.handleData.bind(this)
        />
        <Chart data=this.state.data />
      </div>
    );
  

子组件:

const Chart = (props) => 
  const [data, setData] = useState(props.data);
  const svgRef = useRef();

  useEffect(() => 
    // chart definition
  , [data]);

  return (
    <React.Fragment>
      <svg ref=svgRef>
        <g className="x-axis"></g>
        <g className="y-axis"></g>
      </svg>
    </React.Fragment>
  );
;

export default Chart;

谢谢

【问题讨论】:

你试过setState这样的this.setState((state, props) =&gt; ( // code here )) 试试this.setState(state =&gt; ( data: [...state.data, result.c.gas] )) 成功了!!!谢谢:D @Mario !!! @user9909204 原因是您必须通过分配一个新值来修改状态,在您的情况下,您正在改变它的值。您介意我在答案中发表评论并将其标记为正确吗? @Mario 是的,请! 【参考方案1】:

您需要为状态变量分配一个新值。请试试这个

this.setState(state => ( data: [...state.data, result.c.gas] ))

在你的情况下,你正在改变它的价值

【讨论】:

【参考方案2】:

问题来了

const [data, setData] = useState(props.data);
const svgRef = useRef();

useEffect(() => 
  // chart definition
, [data]);

在首次渲染 Chart 组件时,您会使用来自父组件的数据创建本地数据。使用useEffect,您正在查看本地数据(不是来自父级的数据),但它永远不会改变,因为您从未在Chart 组件内部调用setData。如果它确实有效,那么本地状态将是不可能的。

解决方案是直接使用来自父级的数据并将您的// chart definition 直接放在Chart 中,而不是在useEffect

const Chart = (props) => 
  const svgRef = useRef();
  // chart definition

  return (
    <React.Fragment>
      <svg ref=svgRef>
        <g className="x-axis"></g>
        <g className="y-axis"></g>
      </svg>
    </React.Fragment>
  );
;

export default Chart;

【讨论】:

【参考方案3】:

感谢cmets中的@Mario,我发现了问题,首先我从子组件中删除了状态,并在useEffect中使用了道具,然后@Mario说我改变了

     this.setState((state) => 
        state.gas.push(result.c.gas);
      );

this.setState((state) => ( gas: [...state.gas, result.c.gas] ));

因为,状态甚至没有改变,我只是在我已经拥有的气体数组中添加了一个元素,但是为了改变状态,直接属性应该被辞职。

【讨论】:

以上是关于React js从父事件中更新子状态的主要内容,如果未能解决你的问题,请参考以下文章

状态从父级更改为子级,但未反映到React Hook中的TextField中

从父 React 刷新子状态

React:将状态传递给子组件

我是新来的反应。我想在 React JS 中使用 onClick 事件使用单个状态呈现子组件

React Native - 从父组件重新渲染子组件

如何在 React 中更新 chart.js 的状态