如何更新状态中存在的JSX元素的状态?

时间:2019-05-09 12:15:44

标签: javascript reactjs redux

我在状态中有一个JSX元素和一个计数器,JSX元素在状态中使用了计数器状态。我在modal中显示组件1中的JSX元素,并在component2中设置JSX元素。

当我尝试更新组件2中的计数器时,它不会在组件1中的JSX元素计数器中更改。

组件1

class Meeting extends Component {

    render() {
        const { dispatch, modalVisible, modalContent } = this.props;

        return (
            <Landing>
                <Modal
                    title="Title"
                    visible={modalVisible}
                    onOk={() => { dispatch(showModal(false)); }}
                    onCancel={() => { dispatch(showModal(false)); }}
                    okText="Ok"
                    cancelText="Cancel"
                >
                    <div>
                        {modalContent}
                    </div>
                </Modal>
            </Landing>
        );
    }
}

function mapStateToProps(state) {
    const {
        modalVisible,
        modalContent,
        counter
    } = state.meeting;

    return {
        modalVisible,
        modalContent,
        counter
    };
}

export default connect(mapStateToProps)(Meeting);

组件2

class MeetingItem extends Component {

    state = {
        checked: []
    }

    handleChange = (event) => {
        const { dispatch, counter } = this.props;
        if (event.target.checked) {
            this.setState(() => {
                return { checked: [...this.state.checked, event.target.value] };
            });
            dispatch(setCounter(counter - 1));
        } else {
            const array = this.state.checked;
            const index = array.indexOf(event.target.value);
            if (index > -1) {
                array.splice(index, 1);
                this.setState(() => {
                    return { checked: array };
                });
                dispatch(setCounter(counter + 1));
            }

        }

    };

    isDisable = (val) => {
        const array = this.state.checked;
        const index = array.indexOf(val);
        if (index > -1) {
            return true;
        } else {
            return false;
        }
    }

    showModal = () => {
        const { dispatch, question, counter } = this.props;

        const radioStyle = {
            display: 'block',
            height: '30px',
            lineHeight: '30px',
            marginTop: '6px'
        };

        dispatch(setCounter(0));

        switch (question.question.TypeAnswer) {
            case 'OneAnswer':
                const answers = question.answer.map((record, i) => {
                    return <Radio.Button style={radioStyle} key={i} value={record.Id}>{record.Title}</Radio.Button>
                });
                const modalContent = <div>
                    <p>{question.question.Title}</p>
                    <Radio.Group buttonStyle="solid">
                        {answers}
                    </Radio.Group>
                </div>

                dispatch(setModalContent(modalContent));
                break;
            case 'MultiAnswer':
                dispatch(setCounter(question.question.CountAnswer));

                const multiAnswers = question.answer.map((record, i) => {
                    return <Checkbox key={i} value={record.Id} onChange={this.handleChange}>{record.Title}</Checkbox>
                });
                const multiModalContent = <div>
                    <p>{question.question.Title}</p>
                    <p>counter: {counter}</p>
                    <Checkbox.Group>
                        {multiAnswers}
                    </Checkbox.Group>
                </div>

                dispatch(setModalContent(multiModalContent));
                break;
            case 'PercentAnswer':

                break;
            default: <div></div>
                break;
        }

        dispatch(showModal(true));
    };

    render() {
        const { title, question, fileDoc } = this.props;

        return (
            <Timeline.Item className='ant-timeline-item-right'>
                <span style={{ fontSize: '16px', fontWeight: 'bolder' }}>{title}</span> <span className='textAction' onClick={this.showModal}>showModal</span>
                {/* <br /> */}
                {/* <span>12:00</span>  <Icon type="clock-circle" /> */}
            </Timeline.Item>
        );
    }
}

function mapStateToProps(state) {
    const {
        visibleModal,
        counter
    } = state.meeting;

    return {
        visibleModal,
        counter
    };
}

export default connect(mapStateToProps)(MeetingItem);

动作

export const setCounter = (counter) => (dispatch) => {
    return dispatch({ type: actionTypes.SET_COUNTER, counter })
}

2 个答案:

答案 0 :(得分:5)

您必须在mapDispatchToProps函数中使用connect

...
function mapDispatchToProps (dispatch) {
    propAction: (action) => dispatch(reduxAction(action))
}
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MeetingItem);
...

遵循Auth0

答案 1 :(得分:3)

只需在连接内部使用mapDispatchToProps。