提取Redux后更新状态组件

时间:2018-11-23 15:56:10

标签: javascript reactjs asynchronous redux redux-thunk

首先,对不起我的英语:)

我正在学习React和Redux。我只是想知道为什么我不能使用redux更新一个容器的状态。解决此问题的唯一方法是编写一个设置超时功能(因为JS是异步的)。 但是我敢肯定,有一种更好的方式来编写我想做的事情。如果有人可以帮助我。 我的提取正在运行,没有任何问题。

容器FormAmdmin.js

import React, {Component} from 'react';
import {Container, Row, Col} from 'react-bootstrap';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import {getFormAdmin} from '../Actions/PostFormAdmin';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import './FormAdmin.css'


const MapDispatchToProps = dispatch => {
    return bindActionCreators({getFormAdmin}, dispatch)
}

const MapStateToProps = state => {
    return {Auth : state.Auth}
}

class FormAdmin extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
            isSuccess: false,
            response : {}
        };

    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    }


    componentWillReceiveProps(nextProps){
        console.log(nextProps)
        let response = nextProps.Auth.response
        let isSuccess = nextProps.Auth.isSuccess
        this.setState({
            response,
            isSuccess
        })
        this.onNaviguateAdmin()
   }

    // there 's no change to the state of my component
       onNaviguateAdmin = () => {
       console.log(this.state)
    }

    // It's working thanks to a setTimeOut Fonction
    //    onNaviguateAdmin = () => {
    //     setTimeout(() => {
    //         console.log('succes', this.state)
    //     }, 1000)

    // }


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

    handleSubmit(e){
        e.preventDefault(); 
        const body = {
            email : this.state.email,
            password : this.state.password
        }
       this.props.getFormAdmin(body)
     }

    render() {
    console.log('state render', this.state) // The state in the render is OK
     const { Auth } = this.props
     let divResult = <div></div>
       if (this.state.response.flash ==='ok') {
        divResult = <div>Connexion réussie</div>
       }
       else if (this.state.response.flash ==='Not a yet a Success') {
           divResult = <div>Identifiants ou mot de passe invalides</div>
       }

        return (
            <div className="ContainerFormAdmin">
                <Container fluid>
                    <h3>Administration du site</h3>
                    <Row>
                        <Col xs={12}>
                        <form onSubmit={this.handleSubmit}>
                        <h5>Connexion à l\'Administration</h5>
                            <div>
                            <TextField 

                            name="email"
                            id="email"
                            label="email"
                            margin="normal"
                            onChange={this.handleChange}
                            />
                            </div>
                           <div>
                           <TextField 

                           name ="password"
                           id="password"
                           label="password"
                           margin="normal"
                           onChange={this.handleChange}
                           />
                           </div> 
                           <Button
                           type="submit"
                           >Connexion</Button>

                        </form>

                        </Col>
                    </Row>
                </Container>
                <div>{divResult}</div>

        </div>

        );
    }
}


export default connect(MapStateToProps, MapDispatchToProps)(FormAdmin);

我使用MapDispatchToProps来获取操作:提取。我想获得组件状态下的响应。这就是为什么我使用“ componentWillReceiveProps”来更新我的状态的原因。但这不起作用。

AuthReducer.js

const initialState = {
    error: null,
    response: {},
    isSuccess: false
}

const FormAdmin = (state = initialState, action) => {
    console.log('je rentre dans auth reducers')
    switch (action.type) {
        case 'FORM_ADMIN_SUCCESS':
            if (action.payload.json.flash === 'ok') {
                return {
                    ...state,
                    response: action.payload.json,
                    isSuccess: true
                }
            } else if
                (action.payload.json.flash === 'Not a yet a Success'){
                    return {
                        ...state,
                        response: action.payload.json,
                        isSuccess: false
                    }
                }
        break   
        case 'FORM_ADMIN_ERROR':
            return {
                ...state,
                error: true,
                isSuccess: false
            }

        default:
            return state;
    }
}

export default FormAdmin

操作PostFormAdmin.js

export const postFormAdminSuccess = (json) => ({
    type : 'FORM_ADMIN_SUCCESS', 
    payload : {json}
})

export const postFormAdminError = (error) => ({
    type : 'FORM_ADMIN_ERROR', 
    payload : {error}
})



function handleError(response){

    if (!response.ok){
        throw Error(response.statusText)
    }
   return response
}


export function getFormAdmin(formAdmin){
   return(dispatch) => {
        return fetch('http://localhost:4000/admin', {
            method : 'POST', 
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
              },
            body : JSON.stringify(formAdmin)
        })
        .then(handleError)
        .then(res => res.json())
        .then(
            res => {
                dispatch(postFormAdminSuccess(res));
            },
            err => {
                dispatch(postFormAdminError(err)); 
                console.log('erreur de response', err)
            }
        )
    }
}

我正在使用redux Thunk。

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import allReducers from './Reducers/Index';
import reduxThunk from 'redux-thunk';


const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore); 
const store = createStoreWithMiddleware(
    allReducers
)


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

如果有人可以提供帮助,我真的很感激。我知道它与setTimeout函数一起工作,但是我敢肯定还有另一种方法。

谢谢大家! 空洞的

1 个答案:

答案 0 :(得分:0)

尝试将回调传递给setState,以便在实际更改状态后调用onNaviguateAdmin

this.setState({
    response,
    isSuccess
}, this.onNaviguateAdmin)

请注意,componentWillReceivePropsdeprecated,可能是造成问题的原因。您应该改用componentDidUpdate

componentDidUpdate(prevProps){
    console.log(prevProps, this.props)
    if (this.props.Auth !== prevProps.Auth) {
        let response = this.props.Auth.response
        let isSuccess = this.props.Auth.isSuccess
        this.setState({
            response,
            isSuccess
        }, this.onNaviguateAdmin)
    }
}