React Reducer不会更新State

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Reducer不会更新State相关的知识,希望对你有一定的参考价值。

我的第一个react-redux应用程序让我发疯了。我的Redux State永远不会更新。我试图在网站上找到所有解决方案,但他们没有帮助。 One very similar question在这里使用promise,但我不是。 Redux-dev-tools抓住actions关于login_success,但全球状态永远不会更新,请告诉我如果可以的话我应该怎么做,非常感谢你。

First Index.js

import ... from ... 
const compostEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const rootReducer = combineReducers({
        auth: authReducer,
    })
    const store = createStore(rootReducer, compostEnhancer(
        applyMiddleware(thunk)
    ));

const app = (<BrowserRouter><App /></BrowserRouter>)

ReactDOM.render(<Provider store={store}>{app}</Provider>, document.getElementById('root'));
registerServiceWorker();

authReducer.js:

import * as actionTypes from '../actions/actionTypes';


const initialState = {
    token: null,
    userId: null,
    error: null,
    loading: false
}

const authReducer = (state = initialState, action) => {
    switch (action.types) {
        case actionTypes.LOGIN_START:
            return {
                ...state,
            };

        case actionTypes.LOGIN_SUCCESS:
            return {
                ...state,
                token: action.idToken,
                userId: action.userId,
                loading: false,
                error:null
            }
        default:
            return state;
    }
}

export default authReducer;

authAction.js:

import * as actionTypes from './actionTypes';
import axios from 'axios';

export const loginStart= () =>{
    return {
        type: actionTypes.LOGIN_START
    };
}

export const loginSuccess = (token,userId) =>{
    return {
        type: actionTypes.LOGIN_SUCCESS,
        userId: userId,
        idtoken: token,
    }
}

export const loginFail = (error) =>{
    return {
        type:actionTypes.LOGIN_FAIL,
        error:error
    }
}

export const auth = (email,password,isSignup ) =>{
    return dispatch =>{
        dispatch(loginStart());
        const authData = {
            email: email,
            password: password,
            returnSecureToken:true
        }
        let url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=...'
        if(!isSignup ){
            url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=...'
        }
        axios.post(url, authData)
            .then( response =>{
                console.log(response);
                dispatch(loginSuccess(response.data.idToken, response.data.localId))
            })
            .catch(err=>{
                console.log(err);
                dispatch(loginFail(err));
            })
    }
}

Login.js(组件):

 import ... from ...;

    class Login extends Component {
        constructor(props) {
            super(props);
            this.state = {
                email: "",
                password: "",
                isSignup: false,

            }
            this.handleChange = this.handleChange.bind(this);
            this.handleSubmit = this.handleSubmit.bind(this);
        }
        handleSubmit = e => {
            e.preventDefault();
         // This will trigger actions
            this.props.onAuth(this.state.email, this.state.password, this.state.isSignup);  
            console.log(this.props.token) //here I can Get Token 
        }

        handleChange = (e) => {
            this.setState({ [e.target.name]: e.target.value });
        }

        render() {

            let form =
                <div className={classes.ContactData} >
                    <h4>Sign IN</h4>
                    <form onSubmit={this.handleSubmit} >
                        <Input
                            elementType='input'
                            name="email"
                            required
                            label="Email"
                            placeholder="Email"
                            value={this.state.email}
                            margin="normal"
                            onChange={this.handleChange}

                        />

                        <br />
                        <Input
                            elementType='input'

                            required
                            name="password"
                            value={this.state.password}
                            label="Password"
                            onChange={this.handleChange}
                        />

                        <br />
                        <Button
                            color="primary"
                            type="submit"
                        >Submit</Button>
                        <Button color="primary" href="/"> CANCLE</Button>
                    </form>

                </div>

            if (this.props.loading) {
                form = <Spinner />
            }

            let errorMessage = null;
            if (this.props.error) {
                errorMessage =(
                    <p>{this.props.error.message} </p>
                )

            }

            let token = null;
            if(this.props.token){
                token = this.props.token.toString()
            }

            return (
                <div>
                {errorMessage}
                { form }
                </div>
            )
        }
    }


    const mapStateToProps = state => {
        return {
            loading: state.auth.loading,
            error: state.auth.error,
            token:state.auth.idToken,

        }
    }

    const mapDispatchToProps = dispatch => {
        return {
            onAuth: (email, password, isSignup) => dispatch(actions.auth(email, password, isSignup)),

        }
    }

    export default connect(mapStateToProps, mapDispatchToProps)(Login);

而且,问题导致我的Spinner和显示ErrorMessage无法正常工作。

答案

我想这是一个错字。

代替

switch (action.types) 

试试这个

switch (action.type) 

在reducer中,我们从参数action获取一个从动作返回的对象。

以上是关于React Reducer不会更新State的主要内容,如果未能解决你的问题,请参考以下文章

React Redux reducer 未更新状态

Redux (with React) Reducer switch 语句不更新状态

react-redux笔记

react-redux笔记

react-redux笔记

react-redux笔记