我正在仅使用反应和上下文制作简单的多步骤形式。我尝试使用 react-form-hook,但由于我是 react 新手,因此有点难以理解。 当我在确认后添加用户时,它显示"错误:超出最大更新深度"。提前感谢您的帮助
应用.js
function App() {
return (
<GlobalProvider>
<div className="container">
<UserForm />
</div>
</GlobalProvider>
);
}
GlobalState.jsx
import React, { createContext, useReducer } from 'react';
import AppReducer from './AppReducer';
const initialState = {
users: []
}
// Create context
export const GlobalContext = createContext(initialState);
// Provider component
export const GlobalProvider = ({ children }) => {
const [state, dispatch] = useReducer(AppReducer, initialState);
// Actions
function addUser(user) {
dispatch({
type: 'ADD_USERS',
payload: user
});
}
return (<GlobalContext.Provider value={{
users: state.users,
addUser
}}>
{children}
</GlobalContext.Provider>);
}
AppReducer.jsx
export default (state, action) => {
switch(action.type) {
case 'ADD_USERS':
return {
...state,
users: [action.payload, ...state.users]
}
default:
return state;
}
}
UserForm.jsx
const UserForm = () => {
const [step, setStep] = useState(1);
const [user, setUser] = useState({
firstname: '',
lastname: ''
})
const { firstname, lastname } = user;
const {addUser} = useContext(GlobalContext)
// Go Forward to next step
const nextStep = () => {
setStep(step + 1)
};
// Go back to prev step
const prevStep = () => {
setStep(step - 1)
};
const handleChange = input => e => {
setUser({ ...user, [e.target.name]: e.target.value })
}
if (step === 3) {
const newUser = {
id: Math.floor(Math.random() * 100000000),
firstname,
lastname
}
addUser(newUser)
setTimeout(() => {
setStep(1)
clearAll()
}, 1000);
}
const clearAll = () => {
setUser({
firstname: '',
lastname: ''
})
}
switch (step) {
case 1:
return (<UserInfo
prevStep={prevStep}
user={user}
handleChange={handleChange}
/>);
case 2:
return (<Confirm
nextStep={nextStep}
prevStep={prevStep}
user={user}
/>);
case 3:
return <Succuess />;
default:
return null
}
}
export default UserForm
确认.jsx
const Confirm = ({nextStep, prevStep, user}) => {
return (
<div>
<h1> Confirm</h1>
<div>
<p>{user.firstname}</p>
<p>{user.lastname}</p>
</div>
<button onClick={(e) => prevStep()} type="button" className="btn btn-primary">Back</button>
<button onClick={(e) => nextStep()} type="button" className="btn btn-success">Submit</button>
</div>
)
}
export default Confirm
我认为这段代码应该在函数内并在事件中处理:
const checkFinalStep = () = {
if (step === 3) {
const newUser = {
id: Math.floor(Math.random() * 100000000),
firstname,
lastname
}
addUser(newUser)
setTimeout(() => {
setStep(1)
clearAll()
}, 1000);
}
}
因为目前它只是在组件内部,所以每次 react 需要重新渲染组件时,它都会运行。由于它包含addUser
化简器,因此它会触发更新上下文,进而呈现子项,再次递归地重新呈现组件。