Redux + Selectorunknown 在调用时返回根状态。这可能会导致不必要的重新渲染。 ...警告 + 其中状态是一个数组

问题描述 投票:0回答:1

我在 React 18 应用程序中使用 Redux 5。当使用

useSelector()
包中的
react-redux
方法时,我在浏览器控制台中收到以下警告:

Selector unknown returned the root state when called. This can lead to unnecessary rerenders.
Selectors that return the entire state are almost certainly a mistake, as they will cause a rerender whenever *anything* in state changes.

我还在https://react-redux.js.org/api/hooks#identity-function-state--state-check看到了此警告的redux文档,但是,我面临的问题是我的代码中的“状态是一个数组”。请参阅下面我的文件:

Notes.jsx

import { useDispatch, useSelector } from 'react-redux';
import { toggleImportanceOf } from '../reducers/noteReducer';

const Note = ({ note, handleClick }) => {
  return (
    <li onClick={handleClick}>
      {note.content}
      <strong> {note.important ? 'important' : ''}</strong>
    </li>
  );
};

const Notes = () => {
  const dispatch = useDispatch();
  const notes = useSelector((state) => {
    console.log(state);  // THIS IS AN ARRAY
    return state;
  });

  return (
    <ul>
      {notes.map((note) => (
        <Note
          key={note.id}
          note={note}
          handleClick={() => dispatch(toggleImportanceOf(note.id))}
        />
      ))}
    </ul>
  );
};

export default Notes;

noteReducer.js
是我的减速机

const noteReducer = (state = [], action) => {
  switch (action.type) {
    case 'NEW_NOTE':
      return [...state, action.payload];
    case 'TOGGLE_IMPORTANCE': {
      const id = action.payload.id;
      const noteToChange = state.find((n) => n.id === id);
      const changedNote = {
        ...noteToChange,
        important: !noteToChange.important,
      };
      return state.map((note) => (note.id !== id ? note : changedNote));
    }
    default:
      return state;
  }
};

const generateId = () => Number((Math.random() * 1000000).toFixed(0));

export const createNote = (content) => {
  return {
    type: 'NEW_NOTE',
    payload: {
      content,
      important: false,
      id: generateId(),
    },
  };
};

export const toggleImportanceOf = (id) => {
  return {
    type: 'TOGGLE_IMPORTANCE',
    payload: { id },
  };
};

export default noteReducer;

main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './App';
import noteReducer from './reducers/noteReducer';

const store = createStore(noteReducer);

ReactDOM.createRoot(document.getElementById('root')).render(
  <Provider store={store}>
    <App />
  </Provider>
);

请注意,我知道

createStore
已被弃用。这只是入门课程,我们将学习取代
createStore
方法的新方法。

状态数组如下:

数组内容填充到表单中,然后列表呈现在 UI 上。请看下图:

问题:如何在浏览器控制台中针对数组“状态”修复此警告?

reactjs redux react-redux state useselector
1个回答
0
投票

基本上你不应该有一个返回整个状态对象的选择器函数。

notes
状态嵌套在状态中的
notes
属性下并选择该属性。

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { createStore, combineReducers } from "redux";
import App from "./App";
import noteReducer from "./reducers/noteReducer";

// Create a root reducer function
const rootReducer = combineReducers({
  notes: noteReducer // <-- note reducer forms state.notes
});
const store = createStore(rootReducer);

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>
);
import { useDispatch, useSelector } from "react-redux";
import { toggleImportanceOf } from "./reducers/noteReducer";
import { useEffect } from "react";

const Note = ({ note, handleClick }) => {
  return (
    <li onClick={handleClick}>
      {note.content}
      <strong> {note.important ? "important" : ""}</strong>
    </li>
  );
};

const Notes = () => {
  const dispatch = useDispatch();
  const notes = useSelector((state) => state.notes); // <-- select state.notes array

  useEffect(() => {
    console.log(notes);
  }, [notes]);

  return (
    <ul>
      {notes.map((note) => (
        <Note
          key={note.id}
          note={note}
          handleClick={() => dispatch(toggleImportanceOf(note.id))}
        />
      ))}
    </ul>
  );
};

export default Notes;

另请注意,您还将了解什么是实际上“已弃用”的 Redux。现代 Redux 是使用 Redux-Toolkit 库编写的,该库更加精简且样板代码更少。

© www.soinside.com 2019 - 2024. All rights reserved.