【问题标题】:React js update child state from an event in the parentReact js从父事件中更新子状态
【发布时间】: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 是的,请!

标签: javascript reactjs websocket react-d3


【解决方案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] }));
      

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

      【讨论】:

        猜你喜欢
        • 2021-05-21
        • 1970-01-01
        • 2016-12-26
        • 1970-01-01
        • 1970-01-01
        • 2019-02-14
        • 2015-07-03
        • 1970-01-01
        • 2021-04-02
        相关资源
        最近更新 更多