React中使用d3.csv读取csv多次触发、状态存储异常问题
React项目使用d3.csv读取文件异常解决方案
问题根因
- 现有代码未在csv读取的异步回调中调用
setData方法,读取到的csv数据自然无法存入状态变量 - csv读取逻辑直接写在组件根作用域,每次组件重渲染都会触发一次新的读取请求;同时React 18+默认开启的严格模式会在开发环境下执行两次副作用逻辑,两者共同导致控制台重复打印
修复方案
将csv读取逻辑封装到useEffect钩子中,添加空依赖数组保证仅在组件首次挂载时执行一次,回调内调用setData存储数据:
import logo from './logo.svg'; import './App.css'; import CsvFile from './sentiment.csv' import { csv } from 'd3' import React, { useState, useEffect } from 'react'; function App() { // 可设置初始值为空数组,避免后续取值时报错 const [data, setData] = useState([]) // 仅组件首次挂载时执行csv读取 useEffect(() => { // 增加卸载判断避免组件提前卸载时的状态更新警告 let isMounted = true; csv(CsvFile).then((csvData) => { if (isMounted) { console.log(csvData) setData(csvData) } }) // 组件卸载时修改标记位 return () => { isMounted = false } }, []) return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> {/* 可通过该行验证数据是否存储成功 */} {data.length > 0 && <p>CSV读取完成,共{data.length}条数据</p>} <p> Edit <code>src/App.js</code> and save to reload. </p> </header> </div> ); } export default App;
补充说明
开发环境下严格模式导致的两次执行属于框架自带的调试机制,生产环境构建后会自动消失,无需额外处理。
内容的提问来源于stack exchange,提问作者Vishwak Senan
相关产品推荐
相关产品推荐

