反应将组件作为参数传递给函数

时间:2019-08-07 13:29:42

标签: javascript reactjs function

我有一个将Component作为其参数的函数。该功能使用户可以呈现自己的弹出窗口,而不是我提供的弹出窗口。但是,在将其添加到数组之前,我无法向该组件添加一些道具。

const addCustomSnack = (Snack, position) => {
      let id = generate();

      let snackProps = {
        key: id,
        id,
      };

      Snack.props = {...Snack.props, ...snackProps}
      console.log(Snack);

      buildStyle(position);

      if (messagesNew.length >= 3) {
        que.push(Snack);
        addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, Snack];
        addSnacks(messagesNew);
      }
      console.log(messagesNew);
    };

这就是发生的事情

Cannot assign to read only property 'props' of object '#<Object>'

我尝试了以下代码

const addCustomSnack = (Snack, position) => {
      let id = generate();

      console.log(Snack);

      buildStyle(position);

      if (messagesNew.length >= 3) {
        que.push(Snack);
        addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, <Snack key={id} id={id} />];
        addSnacks(messagesNew);
      }
      console.log(messagesNew);
    };

但是,这将导致React.createElement类型错误。

Codesandbox

有什么办法可以将那些道具成功添加到Snack组件中?

4 个答案:

答案 0 :(得分:0)

这正是React High Order Component的作用:向作为参数传递的组件中添加道具,然后将组件返回。

答案 1 :(得分:0)

如果要在Snack中获取组件,请尝试以下方法

return <Snack {...snackProps} />

使用上述代码,将呈现传递给addCustomSnack的所有组件

答案 2 :(得分:0)

您可以以某种方式保留要渲染的组件数组,每个数组均具有对该组件及其自定义属性的引用,然后使用地图进行渲染,如下所示:

// Snack list
constructor(){
  this.state = { snacks: [] }
}


// ...

const Lollipop = props => (
  <div>
    <h1>Lollipop</h1>
    <span>Taste: </span> {props.taste}
  </div>
)

const ChocolateBar = props => (
  <div>
    <h1>Chocolate bar</h1>
    <span>With fudge: </span> {props.hasFudge ? 'yes': 'no'}
  </div>
)

// Push a custom snack in the list 
const addCustomSnack = (SnackType, props) => this.state.snacks.push({SnackType, props})

// ...
addSnack(Lollipop, {taste: 'cherry'})
addSnack(Lollipop, {taste: 'cola'})
addSnack(ChocolateBar, {hasFudge: true})
addSnack(ChocolateBar, {})

// render the lsit
const SnackList = () => {
  <div>
  { this.state.snacks.map(({SnackType, props}, i) => (
    <SnackType {...props} key={i} />
  ))}
  </div>
}

答案 3 :(得分:0)

React.cloneElement完全符合我的要求。现在,用户可以提供自己的Component,并且可以使用cloneElement扩展组件的props并将其毫无问题地添加到数组中。

const addCustomSnack = (Component, position) => {
      let id = generate();


      let props = {
        removeSnack,
        key: id,
        id,
        index: id
      }

      let Snack = React.cloneElement(Component, { ...props }, null);

      buildStyle(position);


      console.log(Snack)
      if (messagesNew.length >= 3) {
        que.push(Snack);
        return addSnacks(messagesNew);
      } else {
        messagesNew = [...messagesNew, Snack];
        return addSnacks(messagesNew);
      }

    };