简体   繁体   English

从父母到孩子的反应传递道具表现出乎意料

[英]React Passing Props from parent to child behaves unexpectedly

Here is an example of Editing Fields for Product's sizes.以下是产品尺码编辑字段的示例。

产品尺寸

I'm able to edit the size and amount and add the new size and amount.我可以编辑大小和数量并添加新的大小和数量。 Problem comes with deleting it.删除它会带来问题。 When I delete it from bottom everything works as expected:当我从底部删除它时,一切都按预期工作:

删除成功

However when I want to delete from the top or even from the middle instead it deletes the bottom one.但是,当我想从顶部甚至从中间删除时,它会删除底部的。

Here is the Parent of the Edit Component:这是编辑组件的父级:

constructor(props){
   super(props)
   this.state={
      ...

      size: {}
   }
}

handleDeleteSize(obj, prevSize){
    var modSizes = {}
    delete obj[prevSize]
    var newSizes = Object.assign(obj, modSizes)
    this.setState({
        size: newSizes
    })
}

...

<Paper>
   ...

      <EditSizes _sizes={this.state.size} _handleDeleteSize={this.handleDeleteSize.bind(this)}></EditSizes>

</Paper>

Among other props and functions I am passing the state's size object that holds sizes and the amount of products.在其他道具和功能中,我正在传递状态的大小对象,该对象包含大小和产品数量。

Here is the EditSizes Component:这是 EditSizes 组件:

import React from 'react'

// Edit Size
import EditSize from './Edit Size/editsize'

...

class EditSizes extends React.Component {
   constructor(props){
      super(props)
         this.state={
            sizes: {},
      }
   }

   componentDidMount(){
      this.setState({
         sizes: this.props._sizes,
         handleDeleteSize: this.props._handleDeleteSize,

         ...
      })
   }

   render(){
      return(
         <ul>
            {Object.keys(this.state.sizes).map((item, index)=>{
                return <EditSize key={index} _handleDeleteSize={this.state._handleDeleteSize.bind(this)} _otherSizes={this.state.sizes} _size={item} _amount={this.state.sizes[item]}></EditSize>
            })}

            ...
         </ul>
      )
   }
}

export default EditSizes;

This is the place It makes no sense to me.这是对我来说毫无意义的地方。 When I console log each item from the this.state.sizes it console logs it correctly.当我控制台记录 this.state.sizes 中的每个项目时,控制台会正确记录它。 So for example if my sizes are L, M, XL it the console prints just that: L, M, XL.因此,例如,如果我的尺码是 L、M、XL,控制台会打印出:L、M、XL。 But when I pass item to _size prop in EditSize component, for some reason it retains the previous size.但是当我将项目传递给 EditSize 组件中的 _size 道具时,由于某种原因它保留了以前的大小。

For example if I want to delete L size.例如,如果我想删除 L 码。 The console will throw something like this in EditSize component:控制台将在 EditSize 组件中抛出类似这样的内容:

控制台日志

In _otherSizes field I can see the sizes that are remaining after size L has been deleted, but in _size field instead of seeing M, the component for some reason retains the old one.在 _otherSizes 字段中,我可以看到删除尺寸 L 后剩余的尺寸,但在 _size 字段中没有看到 M,组件出于某种原因保留了旧尺寸。 (I use _size as an indicator for which size should be deleted) (我使用 _size 作为应该删除大小的指标)

Here is the EditSize - child component of EditSizes:这是 EditSize - EditSizes 的子组件:

import React from 'react';

// Material UI
import { IconButton, TextField, Paper } from '@material-ui/core';

// Material Icons
import DeleteIcon from '@material-ui/icons/Delete';

// React Bootstrap
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';

class EditSize extends React.Component {
   constructor(props){
      super(props)
         this.state = {
            size: '',
            otherSizes: {},
            amount: '',
            barcode: '',
         }

         ...

         this.handleDelete = this.handleDelete.bind(this)
   }

   componentDidMount(){
      this.setState({
         prevSize: this.props._size,
         size: this.props._size,
         otherSizes: this.props._otherSizes,
         amount: this.props._amount[0],
         barcode: this.props._amount[1]
      })
   }

   componentDidUpdate(prevProps, prevState, snapshot){
      //The Console message comes from here
      console.log(prevProps)
   }

   handleDelete(){
      var prevSize = Object.keys(this.state.otherSizes).find((item)=>item === this.state.size)
      this.props._handleDeleteSize(this.state.otherSizes, prevSize)
   }

   render(){
      return(
         <div>
            <IconButton onClick={()=>this.handleDelete()} aria-label='delete'>
               <DeleteIcon 
                  fontSize='small'
               />
            </IconButton>
            <TextField
               label='Size'
               value={this.state.size}
               onChange={...}
            />
            <TextField
               label='Amount left in this size'
               type='number'
               value={this.state.amount}
               onChange={...}
            />
        </div>
     )
  }
}

export default EditSize;

I'm not sure why when I map this.state.sizes in EditSizes component the item parameter is right, yet it doesn't pass the correct one to the _size prop of EditSize.我不确定为什么当我在 EditSizes 组件中映射 this.state.sizes 时,item 参数是正确的,但它没有将正确的参数传递给 EditSize 的 _size 属性。 What is missing?什么东西少了?

After going through your questions, Have changed some of the implementation of yours看完你的问题后,改变了你的一些实施方式

I don't exactly understand why your are maintaining state in every component.我不完全理解为什么您要在每个组件中维护状态。 You can store the state in one component and use it in the children where ever necessary您可以将状态存储在一个组件中,并在必要时在子组件中使用它

I have changed some of your code, And there are a lot of optimisations that can be done.我已经更改了您的一些代码,并且可以进行很多优化。 Please go through the sandbox and feel free to ask questions.请通过沙盒并随时提问。

Please refer to this sanbox请参考这个沙盒

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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