从父级到子级反应传递道具的行为异常

时间:2020-01-21 14:27:05

标签: javascript reactjs

以下是“产品尺寸编辑字段”的示例。

Product Sizes

我可以编辑尺寸和数量并添加新的尺寸和数量。问题在于删除它。当我从底部删除它时,一切都会按预期进行:

Deletion Successfull

但是,当我想从顶部甚至中间删除时,它会删除底部的。

这里是“编辑”组件的父级:

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>

在其他道具和功能中,我正在传递状态的size对象,该对象保存商品的大小和数量。

这是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.state.sizes控制台记录每个项目时,控制台会正确记录它。因此,例如,如果我的尺寸是L,M,XL,则控制台将仅打印以下内容:L,M,XL。但是当我将项目传递给EditSize组件中的_size prop时,由于某种原因,它将保留先前的大小。

例如,如果要删除L尺寸。控制台将在EditSize组件中抛出以下内容:

Console Log

在_otherSizes字段中,我可以看到删除大小L后剩余的大小,但是在_size字段中,由于某种原因,该组件保留了旧的大小,而不是M。 (我将_size用作要删除其大小的指标)

这是EditSizes-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;

我不确定为什么当我在EditSizes组件中映射this.state.sizes时,item参数是正确的,但是它没有将正确的参数传递给EditSize的_size属性。缺少什么?

1 个答案:

答案 0 :(得分:1)

在回答了您的问题之后,更改了您的一些实现方式

我不完全理解为什么您要维护每个组件的状态。您可以将状态存储在一个组件中,并在必要时在子级中使用它

我更改了您的某些代码,并且可以进行很多优化。请浏览沙盒,随时提问。

请参阅此sanbox