如何使用react-redux设计多个对象的状态?

时间:2020-04-09 00:36:50

标签: reactjs forms react-redux react-state-management

我需要在此处创建多个药品对象。我只想将状态更改为对象数组。如何有效地做到这一点?另外,要实现多种药物对象形式的受控成分。

Form Design

这是我对单个药物对象的要求:

export class MedicineForm extends Component {
    state = {
        medicine_name: "",
        details: ""
    }

    static propTypes = {
        postMedicine: PropTypes.func.isRequired
    }

    onChange = e => {
        this.setState({
          [e.target.name]: e.target.value
        })
    }

    onSubmit = e => {
        e.preventDefault()
        const { medicine_name, details } = this.state
        const medicine = { medicine_name, details }
        this.props.postMedicine(medicine)
        // Following code works as desired.  Need to change state in this JSON Array of objects.

        // this.props.postMedicine([
        //  {
        //      "id": 14,
        //      "medicine_name": "many5",
        //      "details": "sdknas"
        //  },
        //  {
        //      "id": 15,
        //      "medicine_name": "many6",
        //      "details": "sdknas"
        //  }
        // ])
    }

    render() {
        const { medicine_name, details } = this.state

        return (
          <Fragment>
            <h1>Add Medicine</h1>
            <form className="card card-body" onSubmit={this.onSubmit}>
              <div className="form-row">
                <div className="form-group col-md-3">
                  <label htmlFor="medicine_name">Medicine Name</label>
                  <input type="text" className="form-control" name="medicine_name" id="medicine_name" placeholder="Medicine Name" value={medicine_name} onChange={this.onChange} />
                </div>
                <div className="form-group col-md-3">
                  <label htmlFor="details">Details</label>
                  <input type="text" className="form-control" name="details" id="details" placeholder="Details" value={details} onChange={this.onChange} />
                </div>
                <div className="form-group mx-auto mt-3">
                  <button type="submit" className="btn btn-primary btn-lg">
                    Submit
                  </button>
                </div>
              </div>
            </form>
          </Fragment>
        )
    }
}

在操作中,我添加了以下postMedicine方法:

export const postMedicine = (medicine) => dispatch => {
    axios.post('./api/medicine/', medicine)
        .then(res => {
            dispatch({
                type: POST_MEDICINE,
                payload: res.data
            })
        })
        .catch(err => console.log(err))
}

3 个答案:

答案 0 :(得分:1)

//this is one row, add multiple rows as needed        
state = {
    medicines: [{medicine_name: "",
            details: ""
    }]
    }
    //other code

    onChange = (e, i) => {
        const newMedicines = this.state.medicines;
        newMedicines[i] = {[e.target.name]: e.target.value, ...newMedicines[i]}
        this.setState({medicines: newMedicines})
    }

    onSubmit = e => {
        e.preventDefault()
        const { medicine_name, details } = this.state
        const medicine = { medicine_name, details }
        this.props.postMedicine(medicine)
        // Following code works as desired.  Need to change state in this JSON Array of objects.

        // this.props.postMedicine(this.state.medicines)
    }


    <form className="card card-body" onSubmit={this.onSubmit}>
                  {this.state.medicines.map((m, i) => (<div className="form-row">
                    <div className="form-group col-md-3">
                      <label htmlFor="medicine_name">Medicine Name</label>
                      <input type="text" className="form-control" name="medicine_name" id="medicine_name" placeholder="Medicine Name" value={m.medicine_name} onChange={(e) => this.onChange(e, i)} />
                    </div>
                    <div className="form-group col-md-3">
                      <label htmlFor="details">Details</label>
                      <input type="text" className="form-control" name="details" id="details" placeholder="Details" value={m.details} onChange={(e) => this.onChange(e, i)} />
                    </div>
                    <div className="form-group mx-auto mt-3">
                      <button type="submit" className="btn btn-primary btn-lg">
                        Submit
                      </button>
                    </div>
                  </div>))}
                </form>

答案 1 :(得分:0)

表单组件具有两个参数(又称道具)。 第一个是项目,它确定您需要多少个表格。 1表格表示您有两个输入的组[medicine_name,details] 2 = 4输入(2组) ...等

第二个道具是名为 formHandler 的函数。 从孩子那里获得提升数据

Fl::run()

表单组件

export class MedicineForm extends Component {
  state = {
    medicine: [],
  };

  static propTypes = {
    postMedicine: PropTypes.func.isRequired,
  };

  formHandler = (value) => {
    this.setState({ medicine: value });
  };

  onSubmit = (e) => {
    e.preventDefault();
    this.props.postMedicine(this.medicine);
  };

  render() {
    return (
      <>
        <h1>Add Medicine</h1>
        {JSON.stringify(this.state.medicine)}
        <form className="card card-body" onSubmit={this.onSubmit}>
          <Form item="4" formHandler={this.formHandler} />
          <div className="form-group mx-auto mt-3">
            <button type="submit" className="btn btn-primary btn-lg">
              Submit
            </button>
          </div>
        </form>
      </>
    );
  }
}

检查对象是否具有某些值,然后提升数据。 您可以更改逻辑可选

class Form extends Component {
  constructor(props) {
    super(props);
  }
  state = {
    medicine: [...Array(+this.props.item)].map((_, idx) => ({
      id: idx + 1,
      medicine_name: "",
      details: "",
    })),
  };
  static propTypes = {
    item: PropTypes.string,
    formHandler: PropTypes.func,
  };

  onChange = ({ target: { id, name, value } }) => {
    this.setState((prevState) => {
      const medicine = prevState.medicine.map((item) =>
        item.id === Number(id) ? { ...item, [name]: value } : item
      );
      this.props.formHandler(
        medicine.filter((item) => item["medicine_name"] || item["details"])
      );
      return {
        medicine,
      };
    });
  };

  render() {
    return (
      <div className="form-row">
        {this.state.medicine.map((item, id) => (
          <div key={item.id}>
            <div className="form-group col-md-3">
              <label htmlFor="medicine_name">Medicine Name</label>
              <input
                type="text"
                className="form-control"
                name="medicine_name"
                id={item.id}
                value={item.medicine_name}
                placeholder="Medicine Name"
                onChange={this.onChange}
              />
            </div>
            <div className="form-group col-md-3">
              <label htmlFor="details">Details</label>
              <input
                type="text"
                className="form-control"
                name="details"
                id={item.id}
                value={item.details}
                placeholder="Details"
                onChange={this.onChange}
              />
            </div>
          </div>
        ))}
      </div>
    );
  }
}

答案 2 :(得分:-1)

您可以在redux存储中执行以下操作:

[
  { id: 1, medicineName: '', details: '' },
  { id: 2, medicineName: '', details: '' },
  ...
]

要使您的输入字段受到控制,只需处理组件中的状态即可。