0

So first I had a stateless component, and the data is read fine and just in time, and then when, for my needs, I needed to convert it to a stateful component it is not working for some reason like it should. It leaves the data empty for that component. It doesn't even show the Wait... string. This is my current component:

class ItemGroupComponent extends Component {

    constructor(props){
        super(props);
        this.state = {
            userShortcutAreLoading: false,
            labelnameDefinition: [],
            labelnamesAreloading: false,
            itemGroupDefinition: [],
            itemGroupIsLoading: false
        }
    }

    componentDidMount(){
        this.setState({
            userShortcutAreLoading: this.props.userShortcutAreLoading,
            labelnameDefinition: this.props.labelnameDefinition,
            labelnamesAreloading: this.props.labelnamesAreloading,
            itemGroupDefinition: this.props.itemGroupDefinition,
            itemGroupIsLoading: this.props.itemGroupIsLoading
        })
    }

    loadData(e, item){
        console.log(e);
        console.log(item);

    }

    render(){

        if(this.state.labelnamesAreloading === true && this.state.itemGroupIsLoading === true){
            return (<h1> Wait... </h1>) //it doesn't even show the wait...
        }

        console.log("ITEM GROUP");
        console.log(this.state.itemGroupDefinition); //this is always empty
        return (
            <Button ui="button1" arrow={false} ripple={false} iconCls="icon-settings" border={false} >
                <Menu title={this.state.labelnameDefinition['settings.tab.title']} ui='headerMenu'>
                    {this.state.itemGroupDefinition.map((item) =>
                        <MenuItem key={item.id} iconCls={item.iconCls} text={item.name} ui="menuItem1" handler={() => this.loadData}/>
                    )}
                </Menu>
            </Button>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        userShortcutAreLoading: state.coreuireducer.userShortcutAreLoading,
        labelnameDefinition: state.coreuireducer.labelnameDefinition,
        labelnamesAreloading: state.coreuireducer.labelnamesAreloading,
        itemGroupDefinition: state.coreuireducer.itemGroupDefinition,
        itemGroupIsLoading: state.coreuireducer.itemGroupIsLoading
    }
};


const mapDispatchToProps = (dispatch) => {
    return {
        actions: bindActionCreators(itemGroupAction, dispatch)
    }
};


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

-Part of the code which calls ItemGroupComponent:

<NavItem className="d-md-down-none ">
    {/*Search menu*/}
    <NavLink href="#" data-toggle="tooltip" title="Settings">{/*<i className="icon-settings"></i>*/}
      <ItemGroupComponent />
    </NavLink>
</NavItem>

1 Answers1

1

When using redux, you don't use the normal react state pattern. Using mapStateToProps as you have (and assuming your reducer is valid and working) will map your redux-managed state (which you are maintaining in your reducer) to your component's props. So what you want is more like:

class ItemGroupComponent extends Component {

    loadData(e, item){
        console.log(e);
        console.log(item);

    }

    render(){
        const { // destructuring this.props, which now contains your state and is managed using redux
          userShortcutAreLoading,
          labelnameDefinition,
          labelnamesAreloading,
          itemGroupDefinition,
          itemGroupIsLoading
        } = this.props;
        if(labelnamesAreloading === true && itemGroupIsLoading === true){
            return (<h1> Wait... </h1>) //it doesn't even show the wait...
        }

        console.log("ITEM GROUP");
        console.log(itemGroupDefinition); //this is always empty
        return (
            <Button ui="button1" arrow={false} ripple={false} iconCls="icon-settings" border={false} >
                <Menu title={labelnameDefinition['settings.tab.title']} ui='headerMenu'>
                    {itemGroupDefinition.map((item) =>
                        <MenuItem key={item.id} iconCls={item.iconCls} text={item.name} ui="menuItem1" handler={() => this.loadData}/>
                    )}
                </Menu>
            </Button>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        userShortcutAreLoading: state.coreuireducer.userShortcutAreLoading,
        labelnameDefinition: state.coreuireducer.labelnameDefinition,
        labelnamesAreloading: state.coreuireducer.labelnamesAreloading,
        itemGroupDefinition: state.coreuireducer.itemGroupDefinition,
        itemGroupIsLoading: state.coreuireducer.itemGroupIsLoading
    }
};


const mapDispatchToProps = (dispatch) => {
    return {
        actions: bindActionCreators(itemGroupAction, dispatch)
    }
};


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

You might want to read up a little more on redux since it looks like you have a misunderstanding of how it works or how to implement it. I think this looks like a decent tutorial, and the docs are always a good place to start. Also see a related question here.

TrivialCase
  • 1,060
  • 2
  • 14
  • 27