【发布时间】:2020-03-28 22:22:16
【问题描述】:
在向异步调用分派操作后,我正在尝试获取用户的更新状态并将其存储在用户的上下文中。我确实在 reducer 函数中获取了数据,但是返回到我的组件的状态没有改变。
我将异步调用放在我的 reducer 函数中,并在 App.js 中调用 useReducer。之后,我将状态和从 App.js 分派给它可能需要的任何组件。
我可能做错了什么,因为我还是 React 的新手。这是我的尝试:
// UserContext.js
import React from "react";
// create user context
const UserContext = React.createContext({
status: "",
message: "",
username: "",
password: "",
users: []
});
export default UserContext;
// UserReducer.js
import axios from "axios";
// import action
import { AUTH_USER } from "./UserActionTypes";
// import endpoint
import { AUTH } from "../../constants";
// authenticate user
const authenticateUser = async (payload, state) => {
// API call
const response = await axios.post(`${AUTH}?type=${payload.type}`, {
username: payload.username,
password: payload.password
});
const data = response.data;
console.log(`API Data: ${JSON.stringify(data)}`); // data shown
return {
...state,
status: data.status,
message: data.message,
users: data.results
};
};
const UserReducer = async (state, action) => {
switch (action.type) {
case AUTH_USER:
const newState = await authenticateUser(action.payload, state);
console.log(`New State: ${JSON.stringify(newState)}`); // new state shown
return newState;
default:
return state;
}
};
export default UserReducer;
// App.js
import UserContext from "./context/User/UserContext";
import UserReducer from "./context/User/UserReducer";
export default function App() {
// initial state
const initialState = {
status: "",
message: "",
username: "",
password: "",
users: []
};
// useReducer
const [state, dispatch] = useReducer(UserReducer, initialState);
return (
<UserContext.Provider value={{ state, dispatch }}>
<Router history={history}>
<Routes />
</Router>
</UserContext.Provider>
);
}
// Login.js
import React, { useState, useContext } from "react";
import UserContext from "../../context/User/UserContext";
import { AUTH_USER } from "../../context/User/UserActionTypes";
const Login = () => {
const { state, dispatch } = useContext(UserContext);
// initail form data
let initialForm = {
username: "",
password: "",
usernameError: null,
passwordError: null
};
// useState
const [form, setForm] = useState(initialForm);
// submit form
const handleSubmit = e => {
e.preventDefault();
if (!form.username) {
setForm({ ...form, usernameError: "الرجاء إدخال اسم المستخدم" });
return;
}
if (!form.password) {
setForm({ ...form, passwordError: "الرجاء إدخال كلمة المرور" });
return;
}
// dispatch auth action
dispatch({
type: AUTH_USER,
payload: {
username: form.username,
password: form.password,
type: "db"
}
});
console.log(`Context State: ${JSON.stringify(state)}`); // here (state) is still empty
};
return (
<DirectionProvider direction={DIRECTIONS.RTL}>
<div className="centered">
<form onSubmit={e => handleSubmit(e)}>
<Pane>
<TextInputField
name="username"
placeholder="اسم المستخدم"
value={form.username || ""}
onChange={e => {
setForm({ ...form, username: e.target.value });
}}
validationMessage={form.usernameError}
/>
<TextInputField
type="password"
name="password"
placeholder="كلمة المرور"
value={form.password || ""}
onChange={e => {
setForm({ ...form, password: e.target.value });
}}
validationMessage={form.passwordError}
/>
<Button type="submit">
تسجيل الدخول
</Button>
</Pane>
</form>
</div>
</DirectionProvider>
);
};
export default Login;
我正在使用: 反应:“^16.12.0”, 反应路由器:“^5.1.2”, react-router-dom: "^5.1.2",
【问题讨论】:
标签: reactjs react-hooks react-context