1

I need to change the "global" state of Redux (I believe it's called storage). This is my code:

reducer

export const user = (state = {}, action) => {
    console.log(4);
    console.log(action.type)
    console.log(action.payload)
    switch (action.type) {
        case C.SET_USER:
            console.log(action.payload);
            return action.payload;
        case C.CLEAR_USER:
            return action.payload;
        default:
            return state;
    }
};

Action:

export const setUser = (user = {}) => {
    console.log(user);
    return {
        type: C.SET_USER,
        payload: user,
    }
};

Calling the action:

const user = {test:true};
setUser(this.state.user);

But if I run this code, it fails and doesn't call the reducer. It calls the action, but not the reducer. What am I missing?

My current app.js code:

export default class App extends Component {
    constructor(p) {
        super(p);
        this.state = {user: null};
    }

    setUser = () => {
        const {uid} = firebase.auth().currentUser;
        firebase.database().ref('Users').child(uid).on('value', r => {
            const user = r.val();
            this.setState({user: user});
            console.log(this.state.user);
            setUser(this.state.user);
        });
    };

    componentWillMount() {
        if (firebase.auth().currentUser) {
            this.setUser();
        }
        firebase.auth().onAuthStateChanged(async () => {
            console.log('authChanged');
            if (!firebase.auth().currentUser) {
                return null;
            }
            this.setUser();
        });
    }


    render() {
        return (
            <div className="App">
                <Nav/>
            </div>
        );
    }
}
Alex Ironside
  • 4,658
  • 11
  • 59
  • 119
  • Share the code which connect the state and props of the component using redux. I think you missed out call the action via props function. – kumar k Jan 03 '19 at 14:20
  • where is your state? you call `setUser( data from state)`, can you show us the state, or you have pass wrong user? instead `const user = {test:true}; you call some from state(maybe undefined) ` – ivica.moke Jan 03 '19 at 14:22
  • @kumark You are right. My parent component is still in the "React" form. But I need the `ComponentWillMount` element for the app to work. Is there a replacement for it in Redux? – Alex Ironside Jan 03 '19 at 14:22
  • @ivica.moke The console doesn't log anything. It's not being called – Alex Ironside Jan 03 '19 at 14:23
  • have you dispatch it? – ivica.moke Jan 03 '19 at 14:25
  • No. I will attach the code – Alex Ironside Jan 03 '19 at 14:25
  • `import {someAction} from './my-action-folder'` inside your component `this.props.someAction()` `export default connect(null,{someAction})(yourComponent);` – ivica.moke Jan 03 '19 at 14:26
  • @ivica.moke I have attached the code. The problem is I need to use the `ComponentWillMount` listener. Can I use it with Redux somehow? – Alex Ironside Jan 03 '19 at 14:28

3 Answers3

1

setUser have to be dispatched and not simply called:

store.dispatch(setUser(user));

But that's not really the react way, you'd better use mapDispatchToProps in your connect function to dispatch actions directly from component props. Something along the lines of:

import { setUser } from 'store/user';
// ...
class UserComponent extends React.Component {
  // ...
  someMethod() {
    this.props.setUser(user);
  }
}
export default connect(
  null,
  ({setUser: setUser})
)(UserComponent);

This allows your React component to be linked to your Redux store in an optimized and bug-free way. That's also the way most developer use, so you're likely to find a lot of docs on this.

Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
1

Example: Your connected Component where you want to use your setUser action with redux

 import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { setUser} from '../../actions';

    class YourComponent extends Component {
     render(){
      // now your redux action is passed to component as prop
      // and you can use it like
     this.props.setUser(some-user);
      return()
     }

}

export default connect(null, {setUser})(YourComponent);
ivica.moke
  • 1,054
  • 2
  • 10
  • 19
1

first of all you have to dispatch action to change the state , second you have to connect your component to the store

to connect your component to the store

...
import { connect } from 'react-redux';
class MyComponent extends React.Component {
     ...
}

export default connect((store) => ({...}))

when you connect your component to the store you will have access to dispatch function in the props

to dispatch action do this :

this.props.dispatch(setUser());

I believe it's called storage

BTW it called store

Ali Faris
  • 17,754
  • 10
  • 45
  • 70