alwasdev
alwasdev

Reputation: 13

React redux do not propagate state

i don't know what im doing wrong.

I thought i got the point how to implement with redux.

My Problem is that the state of the Component is not propagating to the Component after the state changed. I know we have to create new state object and i'm sure im doing it right. But there is no changes.

And the other question is, why the state is in the object "resetLink" see image. Why is it not stored in the state Object?

Please help me to get it work.


Action for the redux:

export const sendResetLink = (email) => {
    return {
        type: RESET_LINK,
        email
    }
}

class App extends React.Component {

    render() {
        return <VisibleResetLink/>

    }
}

This is where the magic with props and dispatch function happens:

import {connect} from 'react-redux';
import SendResetLink from '../components/SendResetLink.jsx';
import {sendResetLink} from '../actions/index'
import _ from 'lodash';

const mapDispatchToProps = (dispatch) => {
    return {
        onClick: (email) => {
            dispatch(sendResetLink(email))
        }
    }
}
const mapStateToProps = (state) => {
    console.log("actual state", state);
    return _.assign({} , {state: state.resetLink});
}

const VisibleResetLink = connect(
    mapStateToProps,
    mapDispatchToProps
)(SendResetLink)


export default VisibleResetLink

This is the Component which load props but never rerender them when they change.

import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';

class SendResetLink extends React.Component {

    constructor(props, email, result) {
        super(props);

        console.log('props',props);

        this.onClick = props.onClick;
        this.result = props.state.result;
        this.input = props.state.email;
    }

     renderResult (result){

        console.log("renderResult",result);
        if(result)
            return <div className="card-panel deep-orange lighten-4">Invalid username and password.</div>
    }

    render() {
        return <div>
            {this.renderResult(this.result)}
            {this.result}
            <form className="col s12" action="/login" method="post" onSubmit={e => {
                e.preventDefault()
                if (!this.input.value.trim()) {
                    return
                }
                this.onClick(this.input.value);
                this.input.value = ''
            } }>
                <div className="row">
                    <div className="input-field col s12">
                        <i className="material-icons prefix">email</i>
                        <input id="email" type="email" name="email" className="validate" ref = {(node) => this.input = node } />
                        <label for="email">Email</label>
                    </div>
                </div>
                <div className="divider"></div>
                <div className="row">
                    <div className="col m12">
                        <p className="right-align">
                            <button className="btn btn-large waves-effect waves-light" type="submit" name="action">Send reset key</button>
                        </p>
                    </div>
                </div>
            </form></div>
    }
}

SendResetLink.propTypes = {
  onClick: PropTypes.func.isRequired,
  state: PropTypes.object.isRequired
}
export default SendResetLink

And this is the other relevant code snippet, where the reducer is implemented.

import _ from 'lodash';

const resetLink = (state = {email:"[email protected]", result:true}, action) => {
    console.log('state', state)
    switch (action.type) {
        case 'RESET_LINK':
                return _.assign({},state,{email: action.email, result: false}); 
        default:
            return state
    }
}
 export default resetLink;

import { combineReducers } from 'redux'
import resetLink from './ResetLinkReducer.jsx'

const resetApp = combineReducers({
  resetLink
})

export default resetApp

import App from './components/app.jsx';

import {Provider} from 'react-redux';
import { createStore } from 'redux';

import { render } from 'react-dom';
import React from 'react';
import resetApp from './reducers/index.js';


let store = createStore(resetApp,{});
console.log(store)
render(<Provider store={store}>
    <App />
</Provider>, document.getElementById('sendResetLinkComponent'));

console logs. After click the renderResult should change to false. But it stays on true

Upvotes: 1

Views: 961

Answers (1)

TimoStaudinger
TimoStaudinger

Reputation: 42450

You set this.result in your SendResetLink component only once in the constructor, which is only executed when the component is instantiated. The constructor will not be executed every time the application's state changes:

this.result = props.state.result;

Instead of assigning this part of the state to an instance attribute of your react component, simply use the props attribute directly in your render() function:

{this.renderResult(this.props.state.result)}

Upvotes: 3

Related Questions