Javascript useState变量返回空数组,同时将其设置为对象数组

Javascript useState变量返回空数组,同时将其设置为对象数组,javascript,reactjs,Javascript,Reactjs,您好,我有一个组件,如下所示:我正在使用usestate钩子将myFeeds变量初始化到feeds数组,并运行一个效果,从ServerSocket.io添加任何数据。但是,当我在控制台记录结果时,myFeeds给了我一个空数组,可能的原因是什么 const Dashboard = ({feeds}) => { useEffect(() => { getFeeds(); // this fetches feeds array }, []); const [myFeeds, setM

您好,我有一个组件,如下所示:我正在使用usestate钩子将myFeeds变量初始化到feeds数组,并运行一个效果,从ServerSocket.io添加任何数据。但是,当我在控制台记录结果时,myFeeds给了我一个空数组,可能的原因是什么

const Dashboard = ({feeds}) => {

useEffect(() => {
getFeeds(); // this fetches feeds array
}, []);

const [myFeeds, setMyFeeds] = useState(feeds);

// useEffect hook to get real time messages and add it to feed

useEffect(() => {
let mount = true;

io.on('created' (data) => {
  if(mount) {
  data && setMyFeeds([...feeds, data]);
  }
 }
}, [])


console.log(feeds); // gives array of objects
console.log(myFeeds); // giving empty array

return(
<FeedBody body={myFeeds} />
);

}

// mapstatetoprops here

我不知道这是否是问题所在,但你采用feeds道具并将其转换为myFeeds状态的方式在以下几个方面肯定是有问题的:

如果父级使用新值再次调用组件,则组件将看不到其提要属性的更新。请记住,传递到useState的值仅在首次创建组件时使用,不会在后续调用组件函数时使用,而是使用组件的当前状态

您在io.on回调中使用的提要可能已过时,因为在useEffect调用中有一个空的依赖项数组;在io.on调用回调函数时,您的组件函数可能已被更新的提要调用,您将在console.log中看到更新的提要,但与setMyData一起使用的提要将与回调函数在首次调用组件函数时关闭的原始提要失效

下面是我在第二章中提到的:

useEffect(() => {
    let mount = true;

    io.on('created' (data) => {
        if(mount) {
            data && setMyFeeds([...feeds, data]);
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^−−−−−−−−−−−− may be stale!
        }
    }
}, [])
您可能希望将io.on调用移出此组件并将其放入父级,并在提要更改时让父级重新呈现此组件

如果您决定不这样做,您需要做的最小更改是不使用stale feeds参数值。相反,请使用回调表单:

useEffect(() => {
    let mount = true;

    io.on('created' (data) => {
        if(mount) {
            data && setMyFeeds(myFeeds => [...myFeeds, data]);
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^−−−−−−−^^^^^^^−−−−−−−−−−−− up to date
        }
    }
}, [])
但同样,您的组件将丢失对Aren未发送的提要的更新


关于使用钩子时将道具复制到状态可能是一本有用的书。

请用演示问题的方法更新您的问题,最好是使用[]工具栏按钮的堆栈片段运行问题。堆栈代码段支持React,包括JSX。您必须使用setTimeout来模拟io.on内容,否则应该可以在堆栈片段中复制此内容。您在何处以及如何更新从getFeeds接收的提要?能否显示getFeeds函数?看起来父组件接收提要是异步操作的结果,我认为您需要另一个useEffect钩子来监视props.feed中的更改并在那里设置状态。iffeeds设置myFeeds feeds,myFeeds的初始状态可以是空数组。先生,我尝试过这种方法,每当有人发布一个feed时,实时更新myFeeds myFeeds。myFeeds应该用发布的feed填充,直到该点以及最新的feed,我认为我错过了一个关键点,因为getFeeds是一个不知道的restful调用实时呼叫,因此馈送道具将过时。我是否应该使用基于事件的方法,在特定类型的事件发生时运行GetFeed?我不知道您的设置,但从表面上看,您使用的事件是好的,我看到代码的问题是feed以两种方式到达组件。这就是为什么我认为处理程序应该在父级中,而不是在这个组件中——或者,当然,这个组件应该自己获取初始的feed集,而不是feed属性。我使用redux mapDispatchToProps获取getFeeds操作并在useEffect中调用它。hook应该将代码转换为组件,然后更新@Yashwantsomayajula中的状态-基本上我是说初始的feed集和更新应该是在同一组件中处理,而不是让仪表板作为道具接收初始提要集,但通过其自己的事件处理程序进行更新。是否在Dashboard的父级、Dashboard或FeedBody中执行此操作取决于您,您比我更了解整个上下文:-
useEffect(() => {
    let mount = true;

    io.on('created' (data) => {
        if(mount) {
            data && setMyFeeds(myFeeds => [...myFeeds, data]);
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^−−−−−−−^^^^^^^−−−−−−−−−−−− up to date
        }
    }
}, [])