如何在使用 useReducer 时在 React JS 中进行优化,循环传递给子组件的状态
How to optimize in react js while working with useReducer, looped over state which is passed to child component
我正在尝试创建待办事项列表。
function App() {
return (
<div className="App">
<UseReducerToDo/>
</div>
);
}
const { useReducer, useState } = React;
const reducer = (state, action) => {
return [...state, { id: Date.now(), ToDo: action, completed: false }];
};
function UseReducerToDo() {
const [state, dispatch] = useReducer(reducer, []);
const [Todo, setTodo] = useState("");
const addToTODO = (e) => {
e.preventDefault();
dispatch(Todo);
};
return (
<div>
<form onSubmit={addToTODO}>
<input
type="text"
value={Todo}
onChange={(e) => setTodo(e.target.value)}
></input>
</form>
{state.length > 0
? state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
: "no pending items"}
</div>
);
}
function DispToDo({ todo }) {
console.log("DispToDo", todo);
return (
<div>
<p>
{todo.ToDo + "->"} status {todo.completed ? "done" : "pending"}
</p>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
现在,代码可以编译并运行良好。问题与性能有关。
应用程序运行时
添加并提交第一个元素时
现在真正的问题出现了
我发现文本框中的每个按键都会刷新子组件 DispToDo
。这是显而易见的,因为每次按键时控制台中的日志都会累加。
state
中没有变化,但 DispToDo
中有刷新。
有什么办法可以优化吗?
尝试渲染 memoized component:
const MemoDispToDo = React.memo(DispToDo);
// ...
.map(todo => <MemoDispToDo key={todo.id} todo={todo} />)
您可以使用 useMemo()
挂钩记忆您的 state.map()
:
const todos = useMemo(() => (
state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
), [state]);
查看下面的完整演示:
function App() {
return (
<div className="App">
<UseReducerToDo/>
</div>
);
}
const { useMemo, useReducer, useState } = React;
const reducer = (state, action) => {
return [...state, { id: Date.now(), ToDo: action, completed: false }];
};
function UseReducerToDo() {
const [state, dispatch] = useReducer(reducer, []);
const [Todo, setTodo] = useState("");
const addToTODO = (e) => {
e.preventDefault();
dispatch(Todo);
};
const todos = useMemo(() => (
state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
), [state]);
return (
<div>
<form onSubmit={addToTODO}>
<input
type="text"
value={Todo}
onChange={(e) => setTodo(e.target.value)}
></input>
</form>
{state.length > 0 ? todos : "no pending items"}
</div>
);
}
function DispToDo({ todo }) {
console.log("DispToDo", todo);
return (
<div>
<p>
{todo.ToDo + "->"} status {todo.completed ? "done" : "pending"}
</p>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我正在尝试创建待办事项列表。
function App() {
return (
<div className="App">
<UseReducerToDo/>
</div>
);
}
const { useReducer, useState } = React;
const reducer = (state, action) => {
return [...state, { id: Date.now(), ToDo: action, completed: false }];
};
function UseReducerToDo() {
const [state, dispatch] = useReducer(reducer, []);
const [Todo, setTodo] = useState("");
const addToTODO = (e) => {
e.preventDefault();
dispatch(Todo);
};
return (
<div>
<form onSubmit={addToTODO}>
<input
type="text"
value={Todo}
onChange={(e) => setTodo(e.target.value)}
></input>
</form>
{state.length > 0
? state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
: "no pending items"}
</div>
);
}
function DispToDo({ todo }) {
console.log("DispToDo", todo);
return (
<div>
<p>
{todo.ToDo + "->"} status {todo.completed ? "done" : "pending"}
</p>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
现在,代码可以编译并运行良好。问题与性能有关。
应用程序运行时
添加并提交第一个元素时
现在真正的问题出现了
我发现文本框中的每个按键都会刷新子组件 DispToDo
。这是显而易见的,因为每次按键时控制台中的日志都会累加。
state
中没有变化,但 DispToDo
中有刷新。
有什么办法可以优化吗?
尝试渲染 memoized component:
const MemoDispToDo = React.memo(DispToDo);
// ...
.map(todo => <MemoDispToDo key={todo.id} todo={todo} />)
您可以使用 useMemo()
挂钩记忆您的 state.map()
:
const todos = useMemo(() => (
state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
), [state]);
查看下面的完整演示:
function App() {
return (
<div className="App">
<UseReducerToDo/>
</div>
);
}
const { useMemo, useReducer, useState } = React;
const reducer = (state, action) => {
return [...state, { id: Date.now(), ToDo: action, completed: false }];
};
function UseReducerToDo() {
const [state, dispatch] = useReducer(reducer, []);
const [Todo, setTodo] = useState("");
const addToTODO = (e) => {
e.preventDefault();
dispatch(Todo);
};
const todos = useMemo(() => (
state.map((todo) => <DispToDo key={todo.id} todo={todo} />)
), [state]);
return (
<div>
<form onSubmit={addToTODO}>
<input
type="text"
value={Todo}
onChange={(e) => setTodo(e.target.value)}
></input>
</form>
{state.length > 0 ? todos : "no pending items"}
</div>
);
}
function DispToDo({ todo }) {
console.log("DispToDo", todo);
return (
<div>
<p>
{todo.ToDo + "->"} status {todo.completed ? "done" : "pending"}
</p>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>