如何管理子组件数组的状态?



我是新手反应的,请原谅我。我的理解状态,尤其是儿童的问题。

perive :我正在尝试创建一个用户可以越来越多的组件的表单 - 在这种情况下,图像。

发生了什么:用户附加了2个或更多图像。用户尝试使用UploadButton组件上传图像,但是两个图像都是相同的。我相信这与两个附属的儿童共享相同的状态有关。

问题:如何在不影响其他附录的孩子的情况下给每个附录的孩子自己的图像?

class Page extends Component
  constructor (props) {
    super(props);
    this.state = { 
      id: '', 
      numChildren: 0,
      images: [],
    }
    this.onAddChild = this.onAddChild.bind(this);
  }
  showModal() {
    this.setState({
      numChildren: 0,
      images: [],
    });
  }
  renderModal() 
    const children = [];
    //Here's my array of child components
    for(var i = 0; i < this.state.numChildren; i += 1) {
        children.push(<this.ChildComponent key={i} />);
    }
    return (
      <ReactModal>
        <this.ParentComponent addChild={this.onAddChild}>
          {children}
        </this.ParentComponent>
      </ReactModal>
    )
  }
  onAddChild = () => {
    this.setState({
      numChildren: this.state.numChildren + 1
    })
  }
  ParentComponent = (props) => (
    <div>
      {props.children}
      <Button onClick={props.addChild}>Add Item</Button>
    </div>
  );
  ChildComponent = () => (
    <div>
      <UploadButton
        storage="menus"
        value={this.state.images}
        onUploadComplete={uri => this.setState({images: uri})}
      />
    </div>
  );
}

这是UploadButton的代码:

import React, { Component } from 'react';
import uuid from 'uuid';
import firebase from '../config/firebase';
class UploadButton extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isUploading: false
    }
  }
  handleClick() {
    const input = document.createElement("INPUT");
    input.setAttribute("type", "file");
    input.setAttribute("accept", "image/gif, image/jpeg, image/png");
    input.addEventListener("change", ({target: {files: [file]}}) => this.uploadFile(file));
    input.click();
  }
  uploadFile(file) {
    console.log('F', file);
    const id = uuid.v4();
    this.setState({ isUploading: true })
    const metadata = {
      contentType: file.type
    };
    firebase.storage()
      .ref('friends')
      .child(id)
      .put(file, metadata)
      .then(({ downloadURL }) => {
        this.setState({ isUploading: false })
        console.log('Uploaded', downloadURL);
        this.props.onUploadComplete(downloadURL);
      })
      .catch(e => this.setState({ isUploading: false }));
  }
  render() {
    const { 
      props: {
        value,
        style = {},
        className = "image-upload-button",
      },
      state: {
        isUploading    
      }
    } = this;
    return (
      <div 
        onClick={() => this.handleClick()}
        className={className}
        style={{
          ...style,
          backgroundImage: `url("${this.props.value}")`,          
        }}>
        {isUploading ? "UPLOADING..." : !value ? 'No image' : ''}
      </div>
    );
  }
}

export default UploadButton;

我试图排除所有不必要的代码与我的问题有关,但是请让我知道我是否需要显示更多。

编辑:这是我的尝试,它行不通:

//altered my children array to include a new prop
renderModal() {
  const children = [];
  for (var i = 0; i < this.state.numChildren; i += 1) {
    children.push(<this.ChildComponent imageSelect={this.onImageSelect} key={i} />);
  }
  //...
};
//my attempt to assign value and pass selected image back to images array
ChildComponent = () => (
  <div>
    <UploadButton
        storage="menus"
        value={uri => this.props.onImageSelect(uri)} //my greenness is really apparent here
        onUploadComplete={uri => this.setState({images: uri})}
    /> 
    //...
  </div>
);
//added this function to the class
onImageSelect(uri) {
  var el = this.state.images.concat(uri);
  this.setState({
    images: el
  })
}

我知道我无法正确访问孩子。到目前为止,这是我处理的最复杂性。感谢您的时间。

在孩子/父级组件中编写 this.state时,实际上是在访问页面状态。现在,我建议您像这样

将孩子的索引传递给孩子

children.push(<this.ChildComponent key={i} index={i}/>)

,每个孩子都只能处理自己的形象,例如So

ChildComponent = ({index}) => (
    <div>
      <UploadButton
        storage="menus"
        value={this.state.images[index]}
        onUploadComplete={uri => {
          let images = this.state.images.slice()
          images[index] = uri
          this.setState({images})
        }}
      />
    </div>
  );

相关内容

  • 没有找到相关文章

最新更新