#javascript #reactjs #redux #react-hooks #react-component
#javascript #reactjs #redux #реагирующие крючки #реагирующий компонент
Вопрос:
Я новичок в react и впервые пробую перехваты redux и застрял в этой проблеме на один день. Наконец-то подумал о размещении на форуме. Я прилагаю скриншоты кода здесь.
Когда я отправляю форму, сценарий успеха работает довольно хорошо. Он отправляет запрос на серверную часть, где пользователь правильно сохраняется в БД! Проблема связана со случаем ошибки, когда пользователь отправляет форму с уже принятым электронным письмом. В этом случае блок if (auth.error) не вызывается, поскольку состояние не получает объект ошибки из редуктора.
const Signup = () => {
debug('In the Render shit!');
const auth = useSelector((state) => state, shallowEqual);
const dispatch = useDispatch();
const [values, setValues] = useState({
name: 'Rahul',
lastname: 'Kodu',
email: 'rahul.kodu@entr.co',
password: '12345',
success: false,
});
const { name, email, password, success, lastname } = values;
const handleChange = (event) => {
setValues({
...values,
[event.target.name]: event.target.value,
});
};
const handleSubmit = (e) => {
e.preventDefault();
//make thunk call here
debug('Submit Button Clicked');
const user = { name, email, password, lastname };
dispatch(signUpUser(user))
.then(() => {
debug('In then of thunk!');
//Finale
debug(auth);
if (auth.error) {
setValues({ ...values, success: false });
toast.error('Email Already Taken');
} else {
toast.info('🏃 Signed Up! Now Sign in!');
setValues({
email: '',
password: '',
name: '',
lastname: '',
success: true,
});
}
//finale
})
.catch((err) => {
debug('In err of thunk' err);
});
};
const successMessage = () => {
if (success) {
return <Redirect to="/signin"></Redirect>;
}
};
const signUpForm = () => {
return (
<div className="row">
<div className="col-md-6 offset-sm-3 text-left">
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="name-field">Name</label>
<input
className="form-control"
type="text"
id="name-field"
name="name"
value={name}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="name-field">Last name</label>
<input
className="form-control"
type="text"
id="lastname-field"
name="lastname"
value={lastname}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="email-field">Email</label>
<input
className="form-control"
type="email"
id="email-field"
name="email"
value={email}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="password-field">Password</label>
<input
className="form-control"
type="password"
id="password-field"
name="password"
value={password}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<button
type="submit"
className="btn btn-sm btn-custom btn-block mt-5"
>
Sign-up!
</button>
</div>
</form>
</div>
</div>
);
};
return (
<Base title="Signup Page" description="Exisitng user? Goto Signin">
{JSON.stringify(auth)}
{signUpForm()}
{successMessage()}
</Base>
);
};
Асинхронная часть действия. Часть thunk, как показано ниже. Ошибка в части promise вызывает проблему.
//thunk
export const signUpUser = (user) => {
return function (dispatch) {
dispatch(beginApiCall());
const options = {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
};
return axios
.post(config.API 'signup', user, options)
.then((response) => {
debug('In success of axios');
dispatch(signUpUserSuccess(response.data));
})
.catch((err) => {
debug('In err of axios');
dispatch(signUpUserFailure(err.response.data));
dispatch(apiCallError());
});
};
};
В редукторе я возвращаю новый объект для случаев сбоя (SIGNUP_USER_FAILURE), используя синтаксис spread для воспроизведения по правилам неизменности.
const authReducer = (state = initialState.auth, action) => {
switch (action.type) {
case types.LOAD_PROFILE:
if (!action.newAuth) {
action.newAuth = state;
}
return action.newAuth;
case types.SIGNUP_USER_SUCCESS:
if (!action.user) {
action.user = state;
}
debug(action.user);
return { ...action.user };
case types.SIGNUP_USER_FAILURE:
return { ...state, ...action.error };
default:
return state;
}
};
Однако состояние обновляется в редукторе, но компонент не получает обновленное состояние для выполнения действия. Но после следующего рендеринга компонент получает данные. Я думаю, что с рендерингом что-то не так. Пожалуйста, помогите мне здесь. Я
Комментарии:
1. Обратный вызов
dispatch(signUpUser(user)).then
имеет устаревшее закрытиеauth
, вы можете использоватьuseEffect
перехват для просмотраauth
, чтобы вызвать setValues и toast . Или вы можете вернутьauth
объект изsignUpUser
2. Привет @HMR, спасибо, я попробую это.
3. Привет, ссылка ниже, я нашел ее очень находчивой. css-tricks.com /…