首页 > 解决方案 > 如何将道具作为道具传递给从父级接收的组件?

问题描述

import React from 'react'

const fruits = [
  { id: 1, text: `mango` },
  { id: 2, text: `apple` },
]

const Fruit = ({ fruit }) => (
  <div>{ fruit.id } - { fruit.name }</div>
)

const Fruits = ({ component }) => (
  <ul>
    { fruits.map( fruit => <li>{ component({ fruit }) }</li> ) }
  </ul>
)

export const Parent = () => (
  <div>
    <Fruits component={ <Fruit /> } />
  </div>
)

如上例所示,prop 不能从父级传递,因为 prop 是从子级循环的对象数组中获得的。

当我运行此代码时,它显然会引发错误:

TypeError:组件不是函数

我该如何处理?

标签: reactjsreact-native

解决方案


有几个选项:

  1. 克隆元素并为其添加道具。
import React, { cloneElement } from "react";

export const Parent = () => (
  <div>
    <Fruits component={<Fruit />} />
  </div>
);

const Fruits = ({ component }) => (
  <ul>
    {fruits.map((fruit) => (
      <li>{cloneElement(component, { fruit })}</li>
    ))}
  </ul>
);

我通常会避免这样做。cloneElement确实有一些用途,但使用它并不常见,因此可能不熟悉,因此难以理解和维护。另外,我认为您的方案有更好的选择:

  1. 传递一个组件,而不是一个元素,并让孩子把它变成一个元素
export const Parent = () => (
  <div>
    <Fruits component={Fruit} />
  </div>
);

const Fruits = ({ component: Component }) => (
  <ul>
    {fruits.map((fruit) => (
      <li>
        <Component fruit={fruit} />
      </li>
    ))}
  </ul>
);

这很简单,但它确实使两个组件紧密耦合。Parent 和 Fruits 需要在同一页面上准确了解将要发送到其他组件的道具。如果您使用这种方法的方式有限,我会使用这种方法,因此您不介意它不是很灵活。

  1. 传递一个知道如何从道具创建元素的函数,并让孩子使用道具调用该函数。
export const Parent = () => (
  <div>
    <Fruits component={(props) => <Fruit fruit={props.fruit} />} />
  </div>
);

const Fruits = ({ component }) => (
  <ul>
    {fruits.map((fruit) => (
      <li>{component({ fruit })}</li>
    ))}
  </ul>
);

这减少了组件之间的耦合,因为 Fruits 不再假设子组件的 props 的名称是什么。这种方法通常被称为“渲染道具”。如果您需要更高级别的灵活性,我会使用这种方法。


推荐阅读