简体   繁体   中英

React-redux component is not re-rendering after state change

One of my react-redux components is not re-rendering after state change. I want the select to become enabled after the checkbox is checked. But that doesn't happen. Only if I click somewhere else on the page on another component that triggers re-rendering, everything becomes as I expected. What am I doing wrong? I would be grateful for any help.

class Select extends React.Component {
    constructor(props) {
        super(props);
    }

render() {
    return (
        <div>
            <input type="checkbox" onClick={this.props.toggleSelect}/>
            <select disabled={ !Object.keys(this.props.syncObjects).includes("select") }>
            // some options 
            </select>
        </div>
    )
}
}

const mapDispatchToProps = {
    toggleSelect
}

const mapStateToProps = state => {
    return {
        syncObjects: state.json.objects
    }
}

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

// reducer file
const initialState = {
    objects: {}
}

export const myReducer = (state = initialState, action) => {
    switch (action.type) {
        case TOGGLE_SELECT:
            if (Object.keys(state.objects).includes("select")){
                const new_state = {...state}
                delete new_state.objects["select"]
                return new_state
            }
            else {
                return {
                    ...state,
                    objects: {
                        ...state.objects,
                        'select': ''
                    }
                }
            }

        default:
            return state
    }
}

// actions.js
export function toggleSelect() {
    return {
        type: TOGGLE_SELECT
    }
}

Best to not mutate state.updates, you can do the following:

const objects = { ...state.objects };
if (objects.select) {
  delete objects.select;
} else {
  objects.select = true; //set it truthy
}
return {
  ...state,
  objects,
};

Working example:

 const { Provider, connect } = ReactRedux; const { createStore, applyMiddleware, compose } = Redux; const initialState = { objects: {}, }; //action types const TOGGLE_SELECT = 'TOGGLE_SELECT'; // actions.js function toggleSelect() { return { type: TOGGLE_SELECT, }; } const reducer = (state = initialState, action) => { switch (action.type) { case TOGGLE_SELECT: const objects = { ...state.objects }; if (objects.select) { delete objects.select; } else { objects.select = true; //set it truthy } return { ...state, objects, }; default: return state; } }; //creating store with redux dev tools const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( reducer, initialState, composeEnhancers( applyMiddleware(() => (next) => (action) => next(action) ) ) ); class Select extends React.Component { render() { return ( <div> <input type="checkbox" onClick={this.props.toggleSelect} checked={Object.keys( this.props.syncObjects ).includes('select')} /> <div> select enabled: {String( Object.keys(this.props.syncObjects).includes( 'select' ) )} </div> <div> select enabled (simpler example): {String(Boolean(this.props.syncObjects.select))} </div> </div> ); } } const mapDispatchToProps = { toggleSelect, }; const mapStateToProps = (state) => { return { syncObjects: state.objects, }; }; const App = connect( mapStateToProps, mapDispatchToProps )(Select); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM