在React中动态更改组件的子项

时间:2017-01-22 20:06:15

标签: javascript reactjs

是否可以动态更改组件的子项?我有一个包装其他组件的组件,递归地走过孩子们,我想要的是改变子串的文本。 e.g。

export class calculator

设置childNode.props.children ===""在其他内部失败,孩子是只读的。 知道如何实现我的目标吗?

3 个答案:

答案 0 :(得分:6)

React道具的读取确实如React docs中所述。您可以遵循JSX方法,它始终创建新元素,而不是更改现有元素道具。在稍后阶段,元素与虚拟DOM中的现有React组件协调。

要通过JavaScript更改元素的道具,您可以使用React.cloneElement方法克隆元素。请注意,在这种情况下,不应渲染this.props.children,而是渲染新的结果元素树:

render() {
   const func = (children) => {
    return React.Children.map(children, (childNode) => {
      if (typeof childNode === "string")
        return "something"; // cover case: <div>text<div></div></div>
      if (typeof childNode.props.children === "string")
        return React.cloneElement(childNode, [], "something");
      return React.cloneElement(childNode, [], func(childNode.props.children));
    })
  }

  return <span>{ func(this.props.children) }</span>;
}

答案 1 :(得分:3)

我建议让动态子列表在组件的状态中进行渲染并进行渲染。

<强> JSFiddle

class Hello extends React.Component {

  constructor() {
    super();

    this.state = {
      children: [
        <div>test</div>,
        <div>test2</div>
      ]
    };

    setTimeout(() => {
        this.setState({
        children: [
          <div>new!</div>,
          <div>changed!</div>
        ]
      });
    }, 2000);

  }

  render() {
    return <p>{this.state.children}</p>;
  }

}

ReactDOM.render(
  <Hello />,
  document.getElementById('container')
);

您可以在自己的应用中应用此概念。

答案 2 :(得分:1)

解决方案是迭代this.props.children并创建像这样的自定义子项。

&#13;
&#13;
class Parent extends React.Component {
  constructor(props) {
    super(props);    
    this.state = { no: 'need' };
  }
  
render() {
  
    let children = []; // children 
    let k = 0; // key
    this.props.children.forEach( function(child) {       
      if( "string" === typeof child.props.children ){      
        console.log(child);
        let enew = React.cloneElement( child,  child.props, "new_" + k );
        k++;        
        children.push(enew);  
      }else{
        children.push(child);  
      }
    });  
 

  return <span>{ children }</span>;
 }
}



var NewComponent = React.createClass({
  render: function() {
    return (
       <div className="awesome" style={{border: '1px solid red'}}>
        Hello World!  
      </div>
    );
  }
});


ReactDOM.render(
  <Parent>
    <NewComponent />
    <div>Hello</div>    
    <div>World</div>
  </Parent>,
  document.getElementById('root')
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
&#13;
&#13;

根据您的需要,您甚至可以创建新元素,而不是克隆现有元素。

let enew = React.createElement( 'div',  {key: k, className: 'new'}, "new" );