使用Redux时React输入框值不更新的问题求助
Redux状态更新后输入框显示不更新问题解决
我正在构建一个用Redux做状态管理的React简单应用,能正常创建store、分发action,控制台也能打印出更新后的store状态,但输入框的显示值始终不更新。
代码示例
App.js
import "./styles.css"; import { createStore } from "redux"; import myReducer from "./reducers/reducer.js"; const store = createStore(myReducer); store.subscribe(() => { console.log("current state", store.getState()); }); export default function App() { function updateFName(event) { let action = { type: "UPDATE_FIRST_NAME", payload: event.target.value }; store.dispatch(action); } function updateLName(event) { let action = { type: "UPDATE_LAST_NAME", payload: event.target.value }; store.dispatch(action); } return ( <div className="App"> <h1> Hello {store.getState().fName} {store.getState().lName} </h1> <input value={store.getState().fName} onChange={updateFName} placeholder="First Name" /> <input value={store.getState().lName} onChange={updateLName} placeholder="Last Name" /> </div> ); }
reducer.js
const initialState = { fName: "", lName: "" }; function myReducer(state = initialState, action) { switch (action.type) { case "UPDATE_FIRST_NAME": return { ...state, fName: state.fName + action.payload }; case "UPDATE_LAST_NAME": return { ...state, lName: state.lName + action.payload }; default: return state; } } export default myReducer;
问题原因
- 组件未响应store变化触发重渲染:React组件仅在自身state或props变化时才会重新渲染。当前代码直接在组件中调用
store.getState(),但store更新时组件无法感知,不会重新执行渲染逻辑,导致输入框值不更新。 - Reducer更新逻辑错误:输入框的
event.target.value是当前输入框的完整内容,而reducer里用state.fName + action.payload会把完整值追加到原有状态后,造成状态值重复(比如输入"a"后状态是"a",再输入"b",输入框值是"ab",reducer会把"a"+"ab"变成"aab"),即使组件重渲染,显示也会异常。
修复方案
1. 使用React-Redux的Hooks让组件响应store变化
安装并引入react-redux,用Provider包裹根组件让组件能访问store,再通过useSelector获取状态、useDispatch分发action:
修改后的App.js:
import "./styles.css"; import { createStore } from "redux"; import { Provider, useSelector, useDispatch } from "react-redux"; import myReducer from "./reducers/reducer.js"; const store = createStore(myReducer); function AppContent() { const fName = useSelector(state => state.fName); const lName = useSelector(state => state.lName); const dispatch = useDispatch(); function updateFName(event) { dispatch({ type: "UPDATE_FIRST_NAME", payload: event.target.value }); } function updateLName(event) { dispatch({ type: "UPDATE_LAST_NAME", payload: event.target.value }); } return ( <div className="App"> <h1>Hello {fName} {lName}</h1> <input value={fName} onChange={updateFName} placeholder="First Name" /> <input value={lName} onChange={updateLName} placeholder="Last Name" /> </div> ); } export default function App() { return ( <Provider store={store}> <AppContent /> </Provider> ); }
2. 修正Reducer的更新逻辑
把追加逻辑改成直接替换,因为event.target.value已经是输入框的完整内容:
修改后的reducer.js:
const initialState = { fName: "", lName: "" }; function myReducer(state = initialState, action) { switch (action.type) { case "UPDATE_FIRST_NAME": return { ...state, fName: action.payload }; case "UPDATE_LAST_NAME": return { ...state, lName: action.payload }; default: return state; } } export default myReducer;
内容的提问来源于stack exchange,提问作者Ashutosh Gupta
相关产品推荐
相关产品推荐

