【问题标题】:React JS - How to access props in a child component which is passed from a parent componentReact JS - 如何访问从父组件传递的子组件中的道具
【发布时间】:2018-10-10 22:42:32
【问题描述】:

在我的反应应用程序中,我将我的数据作为道具从父母传递给孩子。在我的子组件中,我可以看到 props 中的数据,但是当我尝试访问数据时,我收到一条错误消息,提示“无法读取未定义的属性”。

我已经编写了如下所示的子组件-

子组件-

import React from 'react';
import ReactDOM from 'react-dom';
import { setData } from '../actions/action'
import { connect } from 'react-redux'

import {
    Accordion,
    AccordionItem,
    AccordionItemTitle,
    AccordionItemBody,
} from 'react-accessible-accordion';


import 'react-accessible-accordion/dist/fancy-example.css';
import 'react-accessible-accordion/dist/minimal-example.css';

const ChildAccordion = (props) => {
    console.log(props);

    return (
        <Accordion>
            <AccordionItem>
                <AccordionItemTitle>
                <h3> Details: 
               { props?
                    props.map(d =>{
                        return <span>{d.key}</span>
                    })
                    :
                    ""
               }

                </h3>
                    <div>With a bit of description</div>
                </AccordionItemTitle>
                <AccordionItemBody>
                    <p>Body content</p>
                </AccordionItemBody>
            </AccordionItem>
        </Accordion>
    )
};



export default  ChildAccordion

父组件-

import React from 'react';
import ReactDOM from 'react-dom';
import ChildAccordion from './ChildAccordion'
import { setData } from '../actions/action'
import { connect } from 'react-redux'

import {
    Accordion,
    AccordionItem,
    AccordionItemTitle,
    AccordionItemBody,
} from 'react-accessible-accordion';


import 'react-accessible-accordion/dist/fancy-example.css';
import 'react-accessible-accordion/dist/minimal-example.css';


class ParentAccordion extends React.Component {

    componentWillMount() {
      //call to action
      this.props.setData();
  }

  getMappedData = (dataProp) =>{
      if (dataProp) { 
        let Data = this.props.dataProp.map(d =>{
            console.log(d);
        })
      }
  }


    render(){
        const { dataProp } = this.props;
        return (
            // RENDER THE COMPONENT
                <Accordion>
        <AccordionItem>
            <AccordionItemTitle>
                <h3>Policy Owner Details: 
               { dataProp?
                    dataProp.map(d =>{
                        return <span>{d.key1}</span>
                    })
                    :
                    ""
               }

                </h3>
            </AccordionItemTitle>
            <AccordionItemBody>
            <ChildAccordion {...dataProp} />
            </AccordionItemBody>
        </AccordionItem>
    </Accordion>
        );
    }
}


const mapStateToProps = state => {
    return {
        dataProp: state.dataProp
    }
};

const mapDispatchToProps = dispatch => ({
  setData(data) {
    dispatch(setData(data));
  }
})
export default connect (mapStateToProps,mapDispatchToProps) (ParentAccordion)

我在内部使用 map 函数,因为我的 api 响应可以是多个对象的数组。

【问题讨论】:

  • console.log() 不可靠。它将显示更新的值。尝试使用:console.log(JSON.parse(JSON.stringify(props)))。我相信您会看到 props 最初可能为 null 或其他内容。在代码中的某处抛出 if 就可以了
  • 我试过了,得到 TypeError: Cannot read property 'props' of undefined.
  • props.map - 请记住 props 是一个对象而不是数组。
  • 你不能映射你的道具,因为它是对象,用 prop.yourlist.map 修复它
  • @jonathangoodman 我的道具有一个对象数组,这是我的 api 响应。

标签: javascript reactjs


【解决方案1】:

一旦你知道你传入的 prop 被称为什么,你就可以像这样在你的子组件中访问它:{props.data.map(item =&gt; &lt;span&gt;{item.something}&lt;/span&gt;}

const Parent = () => {
  return (
     <Child data={[{ id: 1, name: 'Jim' }, { id: 2, name: 'Jane ' }]} />
  );
}

const Child = (props) => {
  return (
    <ul>
      {props.data.map(item => <li key={item.id}>{item.name}</li>)}
    </ul>
  );
}

【讨论】:

  • 我已经更新了上面的组件。我认为我不能使用 props.data,因为我的 props 拥有整个对象数组。
  • React 会将传递到 JSX 中的组件的 props 作为对象传递给该组件。您的子组件不会以数组形式接收道具。
  • 仍然出现错误 - TypeError: Cannot read property 'map' of undefined
  • 你的属性是数组映射吗?
  • 我的道具是作为子组件中的一个对象出现的,所以我认为这就是问题所在。我还添加了仅当数据未定义但仍然出现错误时才映射的检查。您可以参考我上面的代码。
【解决方案2】:

您正在将 dataProp 作为道具传递给 ChilAccordian。因此,在子组件中,您应该使用 props.dataProp 访问它并在 props.dataProp 上进行映射,而不是直接在 props 上进行映射

儿童手风琴:

  <h3> Details: 
           { Array.isArray(props.dataProp) && props.dataProp.length > 0 ?
                props.dataProp.map(d =>{
                    return <span key={d.id}>{d.key}</span>
                })
                :
                ""
           }

            </h3>

还请记住,当您在循环中生成它们时,您必须向父 Jsx 元素添加唯一键,例如 for loop、.map、.forEach、Object.keys、OBject.entries、Object.values 等,就像我在上面的例子。如果您没有从数据中获得唯一 ID,请考虑将索引添加为唯一的,例如

      <h3> Details: 
           { Array.isArray(props.dataProp) && props.dataProp.length > 0 ?
                props.dataProp.map((d, index) =>{
                    return <span key={"Key-"+index}>{d.key}</span>
                })
                :
                ""
           }

            </h3>

编辑:如果它是一个对象,则执行以下操作并使用方法生成 jsx 元素

getMappedData = dataProp =>{
   if(props.dataProp){
            Object.keys(props.dataProp).map(key =>{
               return <span key={"Key-"+key}>{props.dataProp[key]}</span>
            });
   }else{
       return "";
    }
  }

   <h3> Details: 
          {this.getMappedData(props.dataProp)} 
   </h3>

【讨论】:

  • 我可以把这个map函数放在render方法外的一个函数中,在render方法中使用key吗?
  • 在函数中做 .map 并在 render 方法中使用 key 是什么意思?我没明白你的问题。你能详细说明一下吗
  • 我可以将迭代部分(map 方法)移动到渲染方法之外的单独函数中吗,例如,如果您看到我使用 getMappedData 对 prop 进行迭代。如果是,那我该怎么做使用我的渲染方法中的键值,因为我使用手风琴,我需要访问我的渲染方法中的键和值。
  • 另外,由于 prop 总是作为对象出现,所以我认为 map 方法在这里不起作用。有什么建议吗?
  • @techiequestie 我编辑了我的答案,请看一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2023-01-12
  • 1970-01-01
  • 2020-04-23
  • 2020-08-25
相关资源
最近更新 更多