简体   繁体   中英

Reassigning state from props value

I have a Select component, once an option is clicked, the value is passed up the parent component.

The parent component has an intial value to render the app, but I would like the value to be changed once it receives the new value through props.

My child component has an onChange that receives the prop and passes it to the parent

const AxesChoice = ({ legendChoice, xChoice, updateAxis, updateLegend }) => {
  const [labels, updateLabels] = useState([])

  const { Option } = Select


  return (
    <div>
     <Select
        key="legendChoice"
        style={{ width: 250 }}
        value={legendChoice}
        onChange={event => {
          updateLegend(event)
        }}
      >
        {labels.map(items => (
          <Option key={items} value={items.header}>
            {items.label}
          </Option>
        ))}
      </Select>
    </div>
  )
}

In my Parent component the child component is rendered like this

 <AxesChoice
        xChoice={axisChoice}
        legendChoice={legendChoice}
        updateAxis={updateAxisChoice}
        updateLegend={updateLegendChoice}
      />

Intial state values are being set like this

  const [legendChoice, setLegendChoice] = useState('qualified')

To update legendChoice I have a function

const updateLegendChoice = event => {
    console.log('fired', event)
    // legendChoice = event
    console.log('legendCHoice', legendChoice)
    console.log('event', event)
    setLegendChoice({ legendChoice: event })
    console.log('newLegend', legendChoice)
    axios
      .get(`${BASE_URL}/${axisChoice}/${legendChoice}/${yearChoice}`)
      .then(res => setState(res.data.data))
      .catch(error => console.log(error))
    console.log('newState', state)
  }

At the momemnt the app crashes with a couple warnings Uncaught Error: Objects are not valid as a React child (found: object with keys {legendChoice}). If you meant to render a collection of children, use an array instead. Uncaught Error: Objects are not valid as a React child (found: object with keys {legendChoice}). If you meant to render a collection of children, use an array instead.

Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

I have tried updating the legendChoice by doing this

setLegendChoice(event)

However this outputs

legendCHoice qualified
event role
newLegend qualified

What is the correct way to update the state when the value is from props?

It should be:

setLegendChoice(event.target.value)

When you use the set function it takes just the value, it knows that value is being applied to LegendChoice. Fairly certain you were essentially setting legendChoice = {legendChoice: yourvalue}, so when you called legendChoice here:

value={legendChoice}

You were putting the value equal to an object, not a string.

Figured it out

async calls and state updates don't play nicely toghether, the useEffect hook addresses this

my function now looks like this

const updateLegendChoice = value => {
    setLegendChoice(value)
  }

I've moved my API call out of the function and moved it into a useEffect Hook

useEffect(() => {
    axios
      .get(`${BASE_URL}/${axisChoice}/${legendChoice}/${yearChoice}`)
      .then(res => setState(res.data.data))
      .catch(error => console.log(error))
  }, [legendChoice])

My API call now fires everytime theres a state update on legendChoice .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM