0
votes

new to React/Redux, I am trying to make it so a user can have as many choices with different choice and customAttribute.

For now I have a button they can createUI with to dynamically create a new textfield to input another choice and customAttribute but am completely stumped on how to store such a thing in redux.

I've seen other questions and answers on how to store username and/or password, but have not seen any examples on how to store an object with my full state in it.

My Component

class CreateRIG extends Component<any, any> {
  constructor(props) {
    super(props);

    this.state = {
      rigName: '',
      desc: '',
      choices: [{
        choice: '',
        customAttribute: ''
      }]
    }
  }

  createUI() {
    return this.state.choices.map((el, i) => (
      <div key={i}>
        <FormControl>
          <Select
            id="choice"
            name="choice"
            onChange={this.handleChange.bind(this, i)}
            value={el.choice || ''}
          >
            <MenuItem value=''>
              <em>None</em>
            </MenuItem>
            <MenuItem value='ID'>ID</MenuItem>
            <MenuItem value='PSA'>PSA</MenuItem>
            <MenuItem value='ExternalID'>ExternalID</MenuItem>
          </Select>
        </FormControl>
        <div>
          <TextField name="customAttribute" label="Attribute"
            onChange={this.handleChange.bind(this, i)} value={el.customAttribute || ''} />
    ))
  }

  handleSubmit = (event) => {
    event.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
          <form onSubmit={this.handleSubmit}>
                    <div>
                      <TextField name="rigName"
                        value={this.state.rigName}
                        onChange={event => this.setState({ rigName: event.target.value })}/>
                    </div>
                    <div className={styles.spacing}>
                      <TextField name="description" 
                        onChange={event => this.setState({ desc: event.target.value })}/>
                    </div>
                  {this.createUI()}
                  <Button type="submit" 
                  onClick={this.props.onSubmitForm}>NEXT</Button>
          </form>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onSubmitForm: (rigName, desc, choice, customAttribute) => dispatch({ type: 'FORM_DATA'})
  }
}

const connectedCreateRIGPage = connect(mapStateToProps, mapDispatchToProps)(CreateRIG);
export { connectedCreateRIGPage as CreateRIG };

export default CreateRIG;

Action.tsx

export const createRIGActions = {
    searchInput
};

function searchInput(rigName, desc, choice, customAttribute) {
    return {
        type: createRIGConstants.STORE_FORM,
        rigName,
        desc,
        choice,
        customAttribute
    }
}

Reducer.tsx

const initialState = { 
    results: [] 
};

export function createRIGReducer(state = initialState, action) {
    switch (action.type) {
        case createRIGConstants.STORE_FORM:
            return {
                ...state,
                results: state.results
            }
            // Need to somehow get the data from the form

        default:
            return state
    }
}

How do you store a complex object from a form, into redux state on submit? Right now my onSubmit is console logging the correct object I want so thats nice

1

1 Answers

1
votes

I believe it is just matter what you pass into dispatch. You can add payload there as well.

Try the following:

const mapDispatchToProps = dispatch => {
  return {
    onSubmitForm: (rigName, desc, choice, customAttribute) => dispatch({ type: 'FORM_DATA', payload: {rigName, desc, choice, customAttribute}})
  }
}

Then in your reducer you can access that payload like the following:

export default (state=initialState, action) => {
    switch(action.type) {
        const { payload } = action;
        case 'FORM_DATA':
            return {
                ...state,
                // here you can use data from payload to update the state
            };

Read further here from Redux documentation: Managing Normalized Data

I hope this helps!