Teoman Tıngır
Teoman Tıngır

Reputation: 2866

How to update component state on through out redux

I'm trying to showing modal when user click the edit button. I setup editProject action. When user clicked the edit button, editProject returns true.

But we can turns redux state into props not component states. Then how can we dynamicly update component state when props are changed ?

Here is EditProjectForm component

import React from "react";
import {Modal, Button, Form} from "react-bootstrap"
import {connect} from "react-redux";
import {updateProject} from "../../actions";

class EditProjectForm extends React.Component {

    constructor(props) {
        super(props);

        this.state = {status: true}
    }

    onCloseClick() {
        this.setState({status: false})
    }

    onSubmit(e) {
        //TODO update project
    };

    render() {
        return (
            <Modal show={this.state.status} onHide={this.onCloseClick}>
                <Modal.Header closeButton>
                    <Modal.Title>{this.props.project.title}</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <Form onSubmit={this.onSubmit.bind(this)}
                          style={{backgroundColor: "#f5f5f5", paddingBottom: 30}}>
                        <Form.Group controlId="title" style={{margin: 10}}>
                            <Form.Label column>Project Title</Form.Label>
                            <Form.Control type="text" placeholder="Enter a title"/>
                        </Form.Group>

                        <Form.Group controlId="description" style={{margin: 10}}>
                            <Form.Label column>Project Description</Form.Label>
                            <Form.Control as="textarea" placeholder="Enter description"/>
                        </Form.Group>

                        <Button variant="primary" type="submit" className="float-right" style={{marginRight: 10}}>
                            Save
                        </Button>
                    </Form>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={this.onCloseClick}>
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>
        )
    }
}

const mapper = function (state) {
    return {
        status: state.editProject,
        project: state.selectProject
    }
};

export default connect(mapper, {updateProject})(EditProjectForm)

Upvotes: 0

Views: 247

Answers (2)

ibtsam
ibtsam

Reputation: 1720

You can achieve this in two ways I think,

1- You can use Redux state this.props.status directly in your component instead of this.state.status, this way you would dispatch an action on onCloseClick that would update Redux store and change status to false.

2- Though it's not recommended usually, You can drive state from props using life getDerivedStateFromProps as

static getDerivedStateFromProps(props) {
  return {
           status: props.status
  }
}

Now your component's internal state is derived from props.

You can read more about getDerivedStateFromProps Here

Hope it helps

Upvotes: 1

Ahmed Saber
Ahmed Saber

Reputation: 509

When you connect this component to the store you can access the status using the this.props.status and to update the status you need an action ex updateStatus please read more about the actions: https://redux.js.org/basics/actions

import React from "react";
import {Modal, Button, Form} from "react-bootstrap"
import {connect} from "react-redux";
import {updateProject} from "../../actions";

class EditProjectForm extends React.Component {
    render() {
        return (
            <Modal show={this.props.status} onHide={this.onCloseClick}>
                <Modal.Header closeButton>
                    <Modal.Title>{this.props.project.title}</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <Form onSubmit={this.onSubmit.bind(this)}
                          style={{backgroundColor: "#f5f5f5", paddingBottom: 30}}>
                        <Form.Group controlId="title" style={{margin: 10}}>
                            <Form.Label column>Project Title</Form.Label>
                            <Form.Control type="text" placeholder="Enter a title"/>
                        </Form.Group>

                        <Form.Group controlId="description" style={{margin: 10}}>
                            <Form.Label column>Project Description</Form.Label>
                            <Form.Control as="textarea" placeholder="Enter description"/>
                        </Form.Group>

                        <Button variant="primary" type="submit" className="float-right" style={{marginRight: 10}}>
                            Save
                        </Button>
                    </Form>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={this.onCloseClick}>
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>
        )
    }
}

const mapper = function (state) {
    return {
        status: state.editProject,
        project: state.selectProject
    }
};

export default connect(mapper, {updateProject})(EditProjectForm)

Upvotes: 0

Related Questions