反应setState钩子异步更新问题

时间:2020-09-09 17:56:40

标签: reactjs react-hooks

我正在尝试根据数据更改来更新屏幕上的某些内容。我正在使用带有钩子的React函数组件。当父元素中的数据更新时,我会通过props将其发送到PlayerControls

export const PlayerControls = (props) => {
....

  const [heatmaps, setHeatMaps] = React.useState("");
  const [data, setData] = React.useState(null);

  useEffect(fetchData, [props.videoData]);
  useEffect(updateHeatmaps, [data]);

  function fetchData () {
     d3.csv(require(`./data/${props.videoData}`)).then((d) => setData(d));
  }

  function updateHeatmaps(){
        if (data && data.length) {
            const temp = data.map((item, index) => {
                return (
                    <Heatmap size={[400, 50]} data={item} key={index}/>
                )
            });
        setHeatMaps(temp);
        }
   }

   return (
       <div>
         {heatmaps}
       </div>
   );

}

问题是,尽管这对于初始数据也可以正常使用,但它不会更新屏幕上的heatmaps。现在,我已经熟悉setState钩子是异步的,并且有一些解决方案(例如使用useEffect钩子来更新状态并将状态添加为依赖项),例如{{ 3}}。问题是我正在使用另一个函数更新状态,并且无法在其中或在返回函数中使用useEffect。我真的很感激任何解决方案,这个问题已经困扰了我一段时间,让我想知道这些挂钩和功能组件是否是所有用例的解决方案。

2 个答案:

答案 0 :(得分:1)

如果呈现时存在映射的数据,则代替呈现heatmaps字符串:

export const PlayerControls = (props) => {
    const [data, setData] = React.useState(null);
    useEffect(fetchData, [props.videoData]);

    function fetchData() {
        d3.csv(require(`./data/${props.videoData}`)).then((setData);
    }

    return (
        <div>
            {data?.map((item, index) => (
                <Heatmap size={[400, 50]} data={item} key={index} />
            ))}
        </div>
    );
}

示例片段:

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const getData = () => Promise.resolve(['foo', 'bar']);
const PlayerControls = (props) => {
    const [data, setData] = React.useState(null);
    React.useEffect(fetchData, [props.videoData]);

    function fetchData() {
        getData().then(setData);
    }

    return (
        <div>
            {data && data.map((item, index) => (
                <Heatmap size={[400, 50]} data={item} key={index} />
            ))}
        </div>
    );
}
const Heatmap = ({ data }) => <div>{data}</div>;
ReactDOM.render(<PlayerControls />, document.querySelector('.react'));
</script>
<div class="react"></div>

答案 1 :(得分:0)

因此,正如上面的评论中提到的@CertainPerformance一样,问题不在于 return DefaultButton( screen: screen, txt: 'Entrar', style: kWhiteButtonTextStyle, color: kBlackColor, function: () => globalVariables.NavigationToLoginPage(context), ), 钩子,而是问题出在useState函数内部。显然,在使用updateHeatmap函数时,您的键应该是全局唯一的。我使用.map作为键,并且由于该索引在更新后没有更改,因此反应没有检测到更改,也没有更新index状态。

更改

heatmaps

const temp = data.map((item, index) => {
     return (
             <Heatmap size={[400, 50]} data={item} key={index}/>
            )
     });

解决了我的问题。我希望这可以帮助其他面临类似问题的人!