【问题标题】:How to pass an user-created array to another component?如何将用户创建的数组传递给另一个组件?
【发布时间】:2021-06-30 13:00:25
【问题描述】:

我是 React 新手。事实上,我对任何前端编程语言都很陌生。因此,我遇到了许多非常奇怪,有时甚至是搞笑的问题。我正在努力将数组发送到另一个组件。问题是用户创建了该数组,它是在 render(){return(..)}

中动态创建的
class Home extends Component {
    constructor(props) {
        super(props)
        this.chosenItems = [];
    }

    state = {
      items: [],
    };
// code to import JSON from backend API, irrelevant, that part works fine
    
addItem(item){
     this.chosenItems.push(item);
     console.log(this.chosenItems); //logs created array, everything works like a charm
    }
render() {
      const {items} = this.state;
        return (
//some code
              <div key={item.id}>
                {item.name} {item.price}<img src = {item.url} className="photo"/><button onClick={() => this.addItem(item)}>ADD</button>
              </div>
<Basket dataFromParent = {this.getItems} />
</div>

和篮子类

class Basket extends React.Component {
    constructor(props) {
        super(props);
        this.chosenItems = [];
    }

    state = {
        items: []
      };
    componentDidUpdate()
    {
        this.chosenItems = this.props.dataFromParent;
        console.log(this.props.dataFromParent);
    }
      
      render() {
        return (
            <div>
            <h2>{this.chosenItems}</h2>
            <h2>{this.props.dataFromParent}</h2>
          </div>
        );
      }
    }
export default Basket;

问题是控制台日志显示“未定义”。你能告诉我我做错了什么吗?或者我的整个方法都不正确,我应该寻找其他解决方案?

更新

class Home extends Component {
    state = {
      items: [],
      chosenItems []
    };
// code to import JSON from backend API, irrelevant, that part works fine
    
  addItem(item){
     this.setState(prev => ({
        chosenItems: [...prev.chosenItems, item]
     }))
    }
      render() {
        const {items, chosenItems} = this.state;
          return (
            <div>
            <div><Basket chosenItems ={this.state.chosenItems} /></div>
            <Router>
            <div className="container">
            <ul>
                <Link to="/login">login</Link>
                <Link to="/basket">basket</Link> 
            </ul>
            <Route path="/login" component={Login} />
            <Route path="/basket" component={Basket} />
            </div>
            </Router>
            <div>
            {items.map(item =>
              <div key={item.id}>
                {item.name} {item.price} {item.quantity} <img src = {item.url} className="photo"/><button onClick={() => this.addItem(item)}>Add!</button>
              </div>
            )}
            </div>
            </div> 
          
      );
      }
}
class Basket extends React.Component {
      render() {
        return (
        <div>
            {this.props.chosenItems.map(item =>
              <div key={item.id}>
                {item.name}{item.price}
              </div>
            )}

        </div>
        
        );
      }
    }

这行得通,但是 selectedItems 数组会立即打印在哪里

<Basket chosenItems ={this.state.chosenItems} />

位于按下按钮后。当我点击购物篮重定向时,我得到了

TypeError: Cannot read property 'map' of undefined

【问题讨论】:

  • 如果您不熟悉 react id,强烈建议您开始使用功能组件而不是类组件。您最终将不得不使用它们。所以现在比你已经习惯了课堂上的要好。

标签: reactjs frontend react-component


【解决方案1】:

我在 sn-p 中看到了几个问题 -

  1. 您将 this.getItems 作为道具传递给您的子组件。它从未在父级中定义。我认为它应该是您创建的 items 数组状态。

  2. chosenItems 应该是一个状态,您应该更深入地研究如何更新状态。有一个setState函数,学习一下吧。

  3. 在 child 中,构造函数再次像 parent 一样编写,带有 selectedItems 和不需要的 items。您可以从道具中使用它们。

【讨论】:

    【解决方案2】:

    首先,您必须了解,您未在状态中设置的内容不会导致重新渲染,因此更新的数据不会反映到 UI 或传递给子级。

    其次,从parent传过来的数据不需要再存储到child中,直接从props中使用就可以了

    class Home extends Component {
        state = {
          items: [],
          chosenItems []
        };
    // code to import JSON from backend API, irrelevant, that part works fine
        
      addItem(item){
         this.setState(prev => ({
            chosenItems: [...prev.chosenItems, item]
         }))
        }
      render() {
          const {items} = this.state;
            return (
              <div>
                //some code
                <div key={item.id}>
                    {item.name} {item.price}<img src = {item.url} className="photo"/><button onClick={() => this.addItem(item)}>ADD</button>
                  </div>
                  <Basket chosenItems ={this.state.chosenItems} />
              /div>
           )
       }
    }
          
    
    class Basket extends React.Component {
          
          render() {
            return (
                <div>
                <h2>{this.props.chosenItems.map(item=> <div>{item.name}</div>)}</h2>
              </div>
            );
          }
        }
    
     export default Basket;
    

    【讨论】:

    • 由于某种原因,当数组由 id 组成时它可以工作,但我还有另一个问题。该数组打印在 所在的位置。但是当整个对象被传递时,程序在按下添加按钮后崩溃。
    • 那是因为,为了渲染一个数组,你需要映射它。更新了我的答案
    • 非常感谢。有效。但是有一个小问题。当我单击添加时,数组会立即显示在&lt;Basket chosenItems ={this.state.chosenItems} 所在的位置。当我点击购物篮组件的路由路径时,我得到:TypeError: Cannot read property 'map' of undefined
    • 您没有在上面的问题中显示路线
    • 将路由更改为&lt;Route path="/basket" render={(routeProps) =&gt; &lt;Basket {...routeProps} chosenItems={this.state.chosenItems}/&gt;} /&gt;
    【解决方案3】:

    请查看https://reactjs.org/docs/react-component.html#setstate 如何改变组件的状态。您将在本文档中找到更多基础知识。 您在日志中获得 undefined 的原因是因为 Home 组件中的 this.getItems() 返回 undefined 要么没有这样的方法,要么状态变量本身可能是 undefined

    简而言之:

    当您想将数组传递给子组件时,就像传递任何对象或属性一样简单,例如。 (我希望您想将选择的项目传递给 Basket 组件)

    始终在构造函数中初始化状态。 所以 chooseItems 和 items 应该是 state 和内部构造函数的一部分。

    您的代码应如下所示:

    class Home extends Component {
        constructor(props) {
            super(props)
            this.state = {
                chosenItems: [],
                items: [],
            }
        }
        
        addItem(item){
            this.setState({
                chosenItems: [...this.state.chosenItems, item]
            })
            console.log(this.chosenItems); //logs created array, everything works like a charm
        }
    
        render() {
          const {items, chooseItems} = this.state;
            return (
                items.map(item => {
                    return (
                        <div key={item.id}>
                            {item.name} {item.price}<img src = {item.url} className="photo"/>
                            <button onClick={() => this.addItem(item)}>ADD</button>
                        </div>
                    )
                })
                <Basket dataFromParent={chooseItems} />
                div>
            )
        }
    }
    

    并且 Basket 组件不需要构造函数,因为所需的数据来自父组件:

    class Basket extends React.Component {
          
          render() {
            return (
                <div>
                {this.props.dataFromParent.map(item =>  <h2>{this.props.dataFromParent}</h2>)}
              </div>
            );
          }
        }
    export default Basket;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-07
      • 1970-01-01
      • 2019-01-31
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      相关资源
      最近更新 更多