【问题标题】:React useState() in an AJAX request not ever changing the component state在 AJAX 请求中反应 useState() 不会改变组件状态
【发布时间】:2019-09-06 07:29:46
【问题描述】:

我有一个反应组件,可以让您选择要绘制的数据(基于过滤器和数据类型),然后使用该数据请求服务器,然后使用服务器响应来创建绘图。简化版如下所示:

function Trend(props) {
    const [dataTypes, setDataTypes] = useState([]);
    const [selectedFilter, selectFilter] = useState(null);
    const [selectedDataTypes, selectDataTypes] = useState([]);
    const [plotData, setPlotData] = useState([]);
    const [revision, setRevision] = useState(0);

    // Whenever the plot data type or filter changes, we have to re-calculate the plot data
    useEffect(() => {
        if (selectedDataTypes.length > 0) {
            client.find('plots/trends/series', {fields: JSON.stringify(selectedDataTypes), filter: selectedFilter})
                .then(data => {
                    console.log('New state!');
                    setPlotData(data.map(datum => datum.toJSON()));
                    setRevision(rev => rev + 1);
                })
        }
    }, [selectedDataTypes, selectedFilter]);

    // When we first create the component, request the data types that could be plotted
    useEffect(() => {
        client.find('data_types')
            .then(resources => {
                setDataTypes(resources.map(resource => resource.get('key')));
            })
    }, []);

    // The template
    return (
        <Plot
            revision={revision}
            data={plotData}
            useResizeHandler={true}
            layout={{
                autosize: true
            }}
            style={{
                width: '100%',
                height: '100%'
            }}
        />
    );

}

特别是plotData的值是Plotly data series的数组,每个数组都是一个复杂的嵌套结构。通常,这包括 3 个不同的系列,所以plotData = [{}, {}, {}]

当我更新selectedFilter 时,确实发送了 AJAX 请求,并且我可以在我的服务器上看到返回了新数据。此外,“新状态!”消息被记录。但是,plotData 状态不会改变。即使在此调用之后几秒钟,如果我检查开发工具,我也可以看到状态没有改变。

但是,修订号确实发生了变化。但这是更简单的数据,它是一个整数,而不是一个对象数组。

这是否与我在 AJAX 响应中更改状态有关?还是我的 plotData 太复杂,React 没有意识到它与以前有什么不同?这似乎很有可能,因为 90% 的返回数据在我更改过滤器后是相同的。 React diffing 算法在这里无法区分吗?

【问题讨论】:

  • 这对吗datum.toJSON()?看起来您正在将从服务器收到的 JSON 转换为... JSON?不应该从 JSON 解析数据以便 plotly 可以接受它吗?

标签: javascript reactjs react-hooks


【解决方案1】:

一种解决方案是使用 Axios 库:

useEffect( () => {
         const callAPI = async () => {
             const res = await Axios.post('plots/trends/series', {
                    params: {fields: JSON.stringify(selectedDataTypes), filter: selectedFilter}
              //just play with response here and update state using hooks
                    }
         }
         if (selectedDataTypes.length > 0) {
             callAPI();
         }   
        }, [selectedDataTypes, selectedFilter]);

【讨论】:

  • 您不能将异步函数直接传递给useEffect
  • 是的,正在修复它。我几乎忘记了这一点,所以感谢您更新我。
猜你喜欢
  • 1970-01-01
  • 2019-03-27
  • 2020-08-17
  • 1970-01-01
  • 2020-09-29
  • 2016-08-07
  • 1970-01-01
  • 2020-09-18
  • 2023-04-02
相关资源
最近更新 更多