setState不会导致子项更新

时间:2018-11-19 18:46:52

标签: reactjs

我正在使用react,socket.io和react-apexcharts(或与此相关的任何其他图表库)构建一个相当简单的应用程序。 我敢肯定,我对状态的概念已经足够了解了-我对编程并不陌生,但是,我似乎无法理解问题所在。 我有一个简单的react组件:

export default class NumberCandleStickChart extends Component {
    constructor(props) {
        super(props);

        this.state = {
            options: {
              chart: {
                id: "number-candlestick",
              },
            },
            series: props.series,
            a: props.a
          };

    }        
    render(){
        return (
            <>
            <p>{JSON.stringify(this.state.a)}</p>
            <Chart
              options={this.state.options}
              series={this.state.series}
              type="candlestick"
              width="500"
            />
            </>
        );
    }
}

它的用法如下:

//imports
class App extends Component {
  constructor(props) {
    super(props);
    this.socket = openSocket('http://localhost:4200');

    this.state = {
      connected: false,
      interval: '10s',
      series: [{
        name: "numbers",
        data: []
      }]
    }

    this.handleNumberIn = this.handleNumberIn.bind(this);    
     this.socket.on('newNumber', this.handleNumberIn)
  }

  handleNumberIn(input) {
    const newSeries = [...this.state.series];
    input.data.map(//map to correct format and push to newSeries);
    this.setState({
      series: newSeries
    });
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <p>
            {this.state.connected.toString()}
          </p>
          <NumberCandleStickChart series={this.state.series} a={this.state.series} />
        </header>
      </div>
    );
  }
}

现在,根据docs,有一个道具可以让我看一下状态是否实际上发生了变化,并且确实如此,它可以将数据正确地添加到数组中。 我尝试使用setInterval模拟相同的内容,并且发生相同的情况,并且尝试使用不同的图表库,但仍然没有运气-因此,我假设我做的事情不正确。 应用是使用create-react-app样板创建的,仅此而已。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

在NumberCandleStickChart的构造方法中,行

series: props.series
a: props.a

仅被调用一次。每当App.js中的状态更新时,NumberCandleStickChart接收到的新道具都不会再次映射到其状态。

您不需要NumberCandleStickChart中的this.state.series。您可以直接使用

<Chart
    options={this.state.options}
    series={this.props.series}
    type="candlestick"
    width="500"
 />

您可以对this.state.a

执行相同的操作

答案 1 :(得分:0)

您的问题出在handleNumberIn中。应该是:

handleNumberIn(input) {
  this.setState(prevState => ({
    series: [...prevState.series, input.data.map(/* your map function */)],
  }));
}

具体来说,Array.prototype.map()返回一个带有映射数据的新数组,它不会修改现有的数组。