[英]How to access to set redux props to react state?
This is my code and I try to set email of user to state and set it with other data:这是我的代码,我尝试将用户的电子邮件设置为声明并使用其他数据进行设置:
import React, {Component} from "react";
import PropTypes from "prop-types";
import * as actionCreators from '../../actions/authAction';
import {loadUser, setPass , register} from "../../actions/authAction";
import {connect} from "react-redux";
import { bindActionCreators } from "redux";
import {clearError} from "../../actions/errorAction";
import {toast} from "react-toastify";
import store from "../../store";
class RegisterFinal extends Component {
componentDidMount() {
store.dispatch(loadUser());
}
componentDidUpdate(nextProps) {
if (nextProps.user !== this.props.user) {
this.setState({ email: this.props.user});
}
}
state = {
userName: "",
password: "",
passwordConfirm: "",
email: "",
msg: null
}
static propTypes = {
isAuthenticated: PropTypes.bool,
setPass: PropTypes.bool,
register: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
user : PropTypes.object.isRequired,
};
onSubmit = (e) => {
e.preventDefault();
const {password, userName, email} = this.state
const setPass = {
password, userName, email
}
this.props.setPass(setPass);
const {passwordConfirm} = e.target;
const errors = {};
if (password.value !== passwordConfirm.value) {
errors.passwordMismatch = "Entered passwords do not match.";
console.log(errors)
}
}
onChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
render() {
return (
<div className={"container"}>
<div className={"row row-of-final-register justify-content-center"}>
<div className={"mt-5 register-teacher-inputs-box final-register-teacher-inputs-box"}>
<div className={"final-register-wrapper"}>
<form className={"mt-5"} onSubmit={this.onSubmit}>
<div className={"row"}>
<div className={"col-12"}>
<label
htmlFor={"userName"} className={"text-right username-label"}>
<span>*</span>
</label>
<input type="text" className="form-control w-100" placeholder={"Username"}
name={"userName"}
autoComplete="true"
value={this.userName}
onChange={this.onChange}
onFocus={(e) => e.target.placeholder = ""}
/>
</div>
</div>
<div className={"row"}>
<div className={"col-12 col-lg-6 mt-3"}>
<label
htmlFor={"password"} className={" text-right"}>
<span>*</span>
</label>
<input type="password" className="form-control " placeholder={"Password"}
name={"password"}
value={this.password}
onChange={this.onChange}
onFocus={(e) => e.target.placeholder = ""}
/>
</div>
</div>
<div className={"row mt-3 pt-2"}>
<div className={"col-12 final-register-wrapper final-register-btn"}>
<button type={"submit"} className={"final-register-btn"}>Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
)
}
}
function mapStateToProps (state , ownProperties) {
console.log(state.auth.user)
return {
setPass: state.auth.setPass,
isAuthenticated: state.auth.isAuthenticated,
error: state.error,
auth: state.auth,
user : state.auth.user,
}
};
function mapDispatchToProps(dispatch) {
return bindActionCreators(actionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps
)(RegisterFinal);
When run I have this data in my email state :运行时,我的电子邮件状态中有这些数据:
But when I try to access email get Error that cannot read property 'email' of undefined, I just change email : this.props.user
to email : this.props.user.email
in componentDidUpdate.但是当我尝试访问 email get Error that cannot read property 'email' of undefined 时,我只是在 componentDidUpdate
email : this.props.user
email : this.props.user.email
更改为email : this.props.user.email
。 I actually need to set redux props to react state.我实际上需要设置 redux props 来响应状态。 I'm new in redux.
我是 redux 的新手。 Here share my project : my project
在这里分享我的项目: 我的项目
Here is a working example that will async load a user, set the initial value of a textbox with it's value and submit changes:这是一个工作示例,它将异步加载用户,使用它的值设置文本框的初始值并提交更改:
const { Provider, connect } = ReactRedux; const { createStore, applyMiddleware, compose } = Redux; const { createSelector } = Reselect; const initialState = { user: null, loading: true, //initially set loading to true }; //helper for async const later = (value) => new Promise((resolve) => setTimeout(() => resolve(value), 2000) ); //action types const CHANGE_USER = 'CHANGE_USER'; const CHANGED_USER = 'CHANGED_USER'; const LOAD_USER = 'LOAD_USER'; const LOADED_USER = 'LOADED_USER'; //action creators const loadUser = () => ({ type: LOAD_USER, }); const loadedUser = (user) => ({ type: LOADED_USER, payload: user, }); const changeUser = () => ({ type: CHANGE_USER, }); const changedUser = (user) => ({ type: CHANGED_USER, payload: user, }); // action thunks const loadUserThunk = () => (dispatch) => { dispatch(loadUser()); return later({ email: 'original-email', }).then((user) => dispatch(loadedUser(user))); }; const changeUserThunk = (email) => (dispatch) => { dispatch(changeUser()); return later({ email, }).then((user) => dispatch(changedUser(user))); }; const reducer = (state, { type, payload }) => { if (type === LOAD_USER || type === CHANGE_USER) { return { ...state, loading: true }; } if (type === LOADED_USER || type === CHANGED_USER) { return { ...state, user: payload, loading: false, }; } return state; }; //selectors const selectUser = (state) => state.user; const selectLoading = (state) => state.loading; const selectUserEmail = createSelector( [selectUser], //want to use user?.email but SO babel is too old (user) => user && user.email ); //creating store with redux dev tools const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( reducer, initialState, composeEnhancers( applyMiddleware( ({ getState, dispatch }) => (next) => ( action //simple thunk implementation ) => typeof action === 'function' ? action(dispatch, getState) : next(action) ) ) ); class App extends React.PureComponent { state = { email: '', initial: true, //only initially set from redux }; componentDidUpdate() { if (!this.props.loading && this.state.initial) { this.setState({ email: this.props.email, initial: false, }); } } //arrow function so you don't need to bind for "this" context onSubmit = (e) => { e.preventDefault(); this.props.dispatch(changeUserThunk(this.state.email)); //reset initial this.setState({ initial: true }); }; emailChanged = (e) => this.setState({ email: e.target.value }); componentDidMount() { this.props.dispatch(loadUserThunk()); } render() { return ( <form onSubmit={this.onSubmit}> <input type="text" onChange={this.emailChanged} value={this.state.email} // do not edit when loading disabled={this.props.loading} /> <input type="submit" /> {this.props.loading && 'loading...'} </form> ); } } //do not use store in your components, connect will provide // dispatch on this.props when mapDispatchToProps is // undefined or you can pass an object as mapDispatchToProps const ConnectedApp = connect((state) => ({ email: selectUserEmail(state), //select state.user.email as props.email loading: selectLoading(state), }))(App); ReactDOM.render( <Provider store={store}> <ConnectedApp /> </Provider>, document.getElementById('root') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script> <div id="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.