Search code examples
javascriptarraysreactjsreact-reduxmapstatetoprops

How do I properly map an array in which it's coming from one of my properties defined in mapStateToProps for a select drop down in my form?


The below code is from my NewFighterForm.js file within my app's component folder:

import React from 'react';
import { updateNewFighterForm } from '../actions/newFighterForm.js';
import { connect } from 'react-redux';
import Button from 'react-bootstrap/esm/Button';

const NewFighterForm = ({ formData, updateNewFighterForm, handleSubmit, editMode }) => {
    
    const {name, alias, nationality, division, stance, height, reach, status, champion, win, loss, draw, ko} = formData

    const handleChange = event => {

        const { name, value } = event.target

        debugger

        
        updateNewFighterForm(name, value)
    }

    return (
            <div>
                <h1>Add Fighter</h1>
                <form onSubmit={event => {
                    event.preventDefault()
                    debugger
                    handleSubmit(formData)
                }}>
                    <ol>
                        <ul>
                        <label>Add Name: </label>
                        <br></br> 
                        <input
                            placeholder="Enter Name"
                            name="name"
                            onChange={handleChange}
                            value={name} 
                        />
                        </ul>
                        <label>Add Alias: </label>
                        <br></br>
                        <ul>
                        <input
                            placeholder="Enter Alias"
                            name="alias"
                            onChange={handleChange}
                            value={alias} 
                        />
                        </ul>
                        <label>Add Nationality: </label>
                        <br></br>
                        <ul>
                        <input
                            placeholder="Enter Nationality"
                            name="nationality"
                            onChange={handleChange}
                            value={nationality} 
                        />
                        </ul>
                        <label>Choose Division: </label>
                        <br></br>
                        <select name="division"
                            value={"" + division}
                            onChange={handleChange}>
                            <option  disabled>Choose the following weight division</option>
                            <option value="Flyweight">Flyweight</option>
                            <option value="Bantamweight">Bantamweight</option>
                            <option value="Featherweight">Featherweight</option>
                            <option value="Lightweight">Lightweight</option>
                            <option value="Welterweight">Welterweight</option>
                            <option value="Middleweight">Middleweight</option>
                            <option value="Light Heavyweight">Light Heavyweight</option>
                            <option value="Cruiserweight">Cruiserweight</option>
                            <option value="Heavyweight">Heavyweight</option>
                        </select>
                        <br></br>
                        <label>Choose Fighter's Stance: </label>
                        <br></br>
                        <select name="stance"
                            value={"" + stance}
                            onChange={handleChange}>
                            <option disabled>Choose the following stance type</option>
                            <option value="Orthodox">Orthodox</option>
                            <option value="Southpaw">Southpaw</option>
                        </select>
                        <br></br>
                        <label>Add Height: </label>
                        <br></br>
                        <input
                            placeholder="Enter Height (i.e 5 ft 5 in)"
                            name="height"
                            onChange={handleChange}
                            value={height}
                        />
                        <br></br>
                        <label>Add Reach: </label>
                        <br></br>
                        <input
                            placeholder="Enter Reach (i.e 68 in)"
                            name="reach"
                            onChange={handleChange}
                            value={reach}
                        />
                        <br></br>
                        <label>Are they still fighting?</label>
                        <br></br>
                        <select name="status"
                            value={"" + status}
                            onChange={handleChange}>
                            <option disabled>Choose whether fighter is still competing</option>
                            <option value="inactive">inactive</option>
                            <option value="active">active</option>
                        </select>
                        <br></br>
                        <label>Check if they ever were a World Champion</label>
                        <input
                            type="checkbox"
                            name="champion"
                            defaultChecked={false}
                            value={champion}
                        />
                        <br></br>
                        <label>W:</label>
                        <input
                            placeholder="Enter number of wins"
                            name="win"
                            type="number"
                            pattern="[0-200]*"
                            inputMode="numeric"
                            onChange={handleChange}
                            value={win}
                        />
                        <br></br>
                        <label>L:</label>
                        <input
                            placeholder="Enter number of losses"
                            name="loss"
                            type="number"
                            pattern="[0-200]*"
                            inputMode="numeric"
                            onChange={handleChange}
                            value={loss}
                        />
                        <br></br>
                        <label>D:</label>
                        <input
                            placeholder="Enter number of draws"
                            name="draw"
                            type="number"
                            pattern="[0-200]*"
                            inputMode="numeric"
                            onChange={handleChange}
                            value={draw}
                        />
                        <br></br>
                        <label>KO:</label>
                        <input
                            placeholder="Enter number of KO"
                            name="ko"
                            type="number"
                            pattern="[0-200]*"
                            inputMode="numeric"
                            onChange={handleChange}
                            value={ko}
                        />
                        <br></br>
                        <label>List for Fighter: </label>
                        <br></br> 
                        <select name="lists"
                            onChange={handleChange}>
                            <option disabled>Choose List for Fighter</option>
                        </select>
                        <br></br>             
                        <Button
                            type="submit"
                            value={ editMode ? "Update Fighter" : "Create Fighter" }
                        >Create Fighter</Button>
                    </ol>
                </form>
            </div>       
    )
}
const mapStateToProps = state => {
    // debugger
    return {
        formData: state.newFighterForm,
        lists: state.myLists

    }
};

export default connect(mapStateToProps, { updateNewFighterForm })(NewFighterForm)

The bottom of my form is where I would like to input the drop down select for the user to choose which one of their lists they would like to add the fighter to. In my debugger placed within mapStateToProps, I see the array of lists that is defined in "lists: state.myLists". I would like to be able to properly map the array and show the select option for the user to choose the list. I assume that I will need to add "lists" as one of the destructed properties defined for NewFighterForm (let me know if my understanding is correct). Please let me know if any more details are needed and I will update the post accordingly. Thank You all, much appreciated!


Solution

  • Yes, destructure lists from the props object and, assuming lists is an array, map as normal JSX. Here I'm assuming the lists array contains element objects that have a value and label property to display from, this will need to be tweaked to fit your actual lists array element shape.

    const NewFighterForm = ({
      formData,
      updateNewFighterForm,
      handleSubmit,
      editMode,
      lists, // <-- get lists from props
    }) => {
      ...
    
      return (
        <div>
          <h1>Add Fighter</h1>
          <form
            onSubmit={event => {
              event.preventDefault()
              debugger
              handleSubmit(formData)
            }}
          >
            <ol>
              ...
    
              <label>List for Fighter: </label>
              <br></br> 
              <select
                name="lists"
                onChange={handleChange}
              >
                <option disabled>Choose List for Fighter</option>
                {lists.map(listItem => ( // <-- map the list
                  <option value={listItem.value}> // <-- the option value
                    {listItem.label} // <-- what you want displayed
                  </option>
                ))}
              </select>
    
              ...
            </ol>
          </form>
        </div>       
      )
    };
    
    const mapStateToProps = state => {
      // debugger
      return {
        formData: state.newFighterForm,
        lists: state.myLists
      }
    };