【问题标题】:How do I pull props down into a component?如何将道具下拉到组件中?
【发布时间】:2020-05-07 23:43:47
【问题描述】:

我正在创建一个简单的应用程序,它通过映射工作订单(第一个 API)来创建“卡片”。通过这个 API,需要一个 workersId 从第二个 API 获取工人数据。

这是我的 App.js


  class App extends React.Component{
  constructor(props){
      super(props);

      this.state = {
          orders:[],
          workersData: []
      };
  }

  componentDidMount(){
    fetch('https://www.hatchways.io/api/assessment/work_orders')
      .then(res=> res.json())
      .then(({ orders }) => {
        this.setState({
          orders: orders
        }, () => {
          this.state.orders.map(order => {
            fetch(`https://www.hatchways.io/api/assessment/workers/${order.workerId}`)
              .then(response=> response.json())
              .then(workersData => {
                this.setState({
                  workersData: workersData
                })
              })
          })
        });
      })
      .catch(err => {
        console.log(err)
      });
  }

  render(){
    const { orders, workersData } = this.state;
      return(
       <CardList orders={ orders } workersData={ workersData } />
      );
  }
}

export default App;

我将 'orders' 和 'workersData' 道具携带到我的 'CardList' 组件中,以便我可以尝试映射每条数据并将其放置在单独的卡片中。

const CardList = props => {
    console.log(props) //<-- this contains the 'orders' and 'workersData'

    const workOrderJsx = props.orders.map( order => (
        <Col key={ order.id } md={6} >
            <Card order={order} />
        </Col>
    ))

    return (
        <ListGroup>
            <MDBContainer fluid={true} >
                <MDBRow>
                    {workOrderJsx}
                </MDBRow>
            </MDBContainer>
        </ListGroup>
    );
}

export default CardList;

这一切都很好,但我面临的问题是,通过映射订单,我只能得到带有订单的卡片。如何同时检索与orders 对象中的id 对应的工人信息?

const Card = props => {
    console.log(props) //<-- only order data

    let date = new Date( props.order.deadline * 1000 );
    const newTime = date.toLocaleString()

    return (
        <div className="card-container">
            <h1 className="order-name">{props.order.name}</h1>
            <p className="ml-5 mr-4">{props.order.description}</p>
            <div>
                <h5> Worker: {props.order.workerId} </h5> //<-- this is where I need the workers info to go
            </div>
            <p className="date">{newTime}</p>
        </div>
    )
}

export default Card;

【问题讨论】:

  • 如果我错了,请纠正我,但看起来你只会在你的 App 组件的状态下获得一个订单的workersData。而是你想要this.setState(state =&gt; ({ workersData: [...workersData, newWorkerData]))

标签: javascript reactjs api mapping react-props


【解决方案1】:

您似乎在 fetch 调用中覆盖了地图中的 workersData。您应该从以前的循环迭代中复制现有的 workerData 并将其与当前迭代的 workerData 结合起来。

componentDidMount(){
    fetch('https://www.hatchways.io/api/assessment/work_orders')
      .then(res=> res.json())
      .then(({ orders }) => {
        this.setState({
          orders: orders
        }, () => {
          this.state.orders.map(order => {
            fetch(`https://www.hatchways.io/api/assessment/workers/${order.workerId}`)
              .then(response=> response.json())
              .then(workersData => {
                this.setState({
                  workersData: [...this.state.workersData, workersData]
                })
              })
          })
        });
      })
      .catch(err => {
        console.log(err)
      });
  }

然后您可以将工人数据对象与订单一起传递到您的卡片组件中。在卡片组件中,您可以通过 workerData 对象中的订单 id 查找工作人员信息。

【讨论】:

  • 我将 workerData 传递给我的 CardList 组件没有问题。我确实按照您的建议在其中实现了扩展运算符,但我在 Card 组件中的结果仍然相同。它只是通过发送 order 道具。它还会继续覆盖
  • 你就这样过关了吗?
【解决方案2】:

你可以做的是在你的地图函数中找到与订单相对应的工人。

我猜您的代码需要按照这些思路进行查看。

const CardList = props => {
  console.log(props) //<-- this contains the 'orders' and 'workersData'

  const findWorker = (id) => props.workersData.find(worker => worker.id === id);

  const workOrderJsx = props.orders.map(order => {
    const worker = findWorker(order.id);
    return (
      <Col key={order.id} md={6} >
        <Card order={order} worker={worker}/>
      </Col>
    )
  })

  return (
    <ListGroup>
      <MDBContainer fluid={true} >
        <MDBRow>
          {workOrderJsx}
        </MDBRow>
      </MDBContainer>
    </ListGroup>
  );
}

export default CardList;

【讨论】:

    【解决方案3】:

    首先,您为每个订单获取 workerData 的多个请求总是被新的响应覆盖,这意味着您的 workerData 将只包含最后一个订单的数据。所以你应该在那里使用 Object ,每个 workerData 都将被放置在每个订单上。 结构应该像{ [orderWorkerId]: fetchedWorkerData}

    然后在您的 map 方法中,您可以根据 order.workerId 获取指定的 workerData 并将其传递给您将获取每个订单的正确数据的组件。希望这会有所帮助:)

    更多详情:

    在获取workerData的API调用中,这样做:

    this.setState({workersData: { ...this.state.workersData, [order.workerId]: workersData }

    通过这种方式,您可以根据 order.workerId 维护您的所有 workerData。之后,在您的订单地图方法中这样做:

    &lt;Card order={order} workerData={props.workersData[order.workerId]} /&gt;

    通过这种方式,您将在 Card 组件中获得与您的订单相关的 workerData,您可以随意使用它。 :)

    【讨论】:

    • 你能再具体一点吗。我没有完全理解 Object 的去向
    猜你喜欢
    • 2014-05-13
    • 2021-07-22
    • 1970-01-01
    • 2020-06-02
    • 2021-04-06
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    相关资源
    最近更新 更多