简体   繁体   English

State 在 react-redux useSelector()

[英]State change isn't re-rendering component after axios data fetch in react-redux useSelector()

I'm trying to fetch and display data on the initial load of an application using react and redux.我正在尝试使用 react 和 redux 获取和显示应用程序初始加载的数据。 But the component that should display the data does not have the data by the time it is rendered.但是应该显示数据的组件在渲染时还没有数据。 It eventually gets the data but doesn't re-render for some reason.它最终会获取数据,但由于某种原因不会重新渲染。

Here are my two components in question:这是我有问题的两个组件:

App.js应用程序.js

import React, {useEffect} from 'react';
import './App.css';
import RecordList from './components/RecordList';
import CreateRecord from './components/CreateRecord';
import {useDispatch} from 'react-redux';
import { initRecords } from './actions/recordActions';

function App() {
  const dispatch = useDispatch();

  // Gets initial record list.
  useEffect(() => {
    dispatch(initRecords());
  }, [dispatch])
  return (
    <div className="App">
      <CreateRecord />
      <RecordList/>
    </div>
  );
}

export default App;

RecordList.js记录列表.js

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'


export default function RecordList() {
  const dispatch = useDispatch();
  const records = useSelector(state=>state);
  console.log('state: ', records)
  return (
    <div>
      <h3>Albums</h3>
      {records.map(record =>
        <div key={record.id}>
          {record.albumName} by {record.artist}
        </div>
      )}
    </div>
  )
}

The issue I'm having is that initial data fetch in App.js isn't returning fast enough by the time the RecordList.js component is rendered.我遇到的问题是 App.js 中的初始数据获取在 RecordList.js 组件呈现时返回的速度不够快。 So in RecordList.js this bit throws an error saying map is not a function or cannot map on undefined:所以在 RecordList.js 中这个位会抛出一个错误,说 map 不是 function 或者不能 map on undefined:

{records.map(record =>
        <div key={record.id}>
          {record.albumName} by {record.artist}
        </div>
      )}

The component does eventually get the data if you comment out the JSX throwing the error.如果您注释掉抛出错误的 JSX,组件最终会获取数据。 Initially it logs records as undefined but after a second it logs it with correct values.最初它将记录记录为未定义,但在一秒钟后它使用正确的值记录它。

Here are my reducer and actions: recordActions.js这是我的减速器和动作: recordActions.js

import recordService from '../services/records';

export const initRecords = () => {
  return async dispatch => {
    const records = await recordService.getAll();
    console.log('from actions: ', records);
    dispatch({
      type: 'INIT_RECORDS',
      data: records
    })
  };
}

reducer减速器

const recordReducer = (state = [], action) => {
  console.log('state now: ', state)
  console.log('action', action)
  switch(action.type) {
    case 'CREATE':
      return [...state, action.data];
    case 'INIT_RECORDS':
      return action.data;
    default: return state;
  }
}

export default recordReducer

Lastly, here is where I am making the axios call:最后,这是我拨打 axios 的地方:

service服务

const getAll = async () => {
  const response = await axios.get('someapi.com/records');
  return response.data;
}

I've tried to conditionally render both the entire recordsList component and the records.map but the conditions only check once on the first load and never check again.我尝试有条件地渲染整个recordsList组件和records.map但条件仅在第一次加载时检查一次,并且不再检查。

From my understanding, useSelector() should re-render the component when there's a state change, is it possible the state is just being mutated and not changed and how can I fix this?据我了解,当 state 发生更改时, useSelector()应该重新渲染组件,state 是否可能只是被变异而不被更改,我该如何解决这个问题?

Figured it out!弄清楚了! Turns out in useSelector(state=>state) I needed to change it to useSelector(state=>state.records.Items ) to get to the array.原来在useSelector(state=>state)我需要将其更改为useSelector(state=>state.records.Items ) 才能进入数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM