

Reactで下記のようなコンポーネントを作りました  
data は API を受け取るためのものです

[code]

    const Loop = ({data,children}) => {
       return (
         <ul>{
          data.map((item,index)=> {
            return (
              React.cloneElement(
                children,{
                 item
            })) 
          })
        }</ul>
      );
    };
    
[/code]

しかしこのままだとli要素のコンポーネントしかchildrenに渡せないので汎用的にしたいのですが、  
Reactの性質上何かしらのDOMを返さないといけないのでdivにすると今度はliタグが使えなくなったりと応用が利かなくなってしまいます

ReactでDOMを返さずロジックだけのコンポーネントの作成などはできますか？


CC BY-SA 3.0
2017-02-16T07:26:28.983
32713
2017-03-26T05:14:56.690
20677
question
javascript reactjs react-jsx redux
React の cloneElementをreturn したい


親コンポーネントも一緒に渡すのはどうでしょうか。  
下のスニペットに実装した Loop コンポーネントでは、繰り返される子要素 component と、それを包む wrapper を渡すようにしています。

たとえば `<Loop data={data} component="li" wrapper="ul" />`
のようにすると元の動きになり、別の要素を使いたければ `<Loop data={data} component="p" wrapper="div" />`
のようにします。

また、コンポーネントを渡せるので、`<Loop data={data} component={Hello} wrapper="div" />`
といった使い方もできます。

あるいは下の repeatComponent 関数のように、先程の Loop コンポーネントの配列を作る部分だけを取り出した関数にしても良いと思います。  
JSX では、コンポーネントの中に `{ componentArray }`
のようにコンポーネントの配列を入れると展開されるようになっているので、`{repeatComponent(data, "li")}`
とすると子要素だけを使うことができます。

[code]

    var Hello = React.createClass({
      render: function() {
        return <div>Hello {this.props.name}</div>;
      }
    });
    
    const Loop = ({data, component, wrapper}) => {
      const ItemComponent = component
      const Wrapper = wrapper
      return <Wrapper>
        { data.map((item,index) => <ItemComponent {...item} />) }
      </Wrapper>
    }
    
    const data = [{name: "world"}, {name: "again"}]
    
    const repeatComponent = (data, ItemComponent) => {
      return data.map((item,index) => <ItemComponent {...item} />)
    }
    
    ReactDOM.render(
      <div>
       <Loop data={data} component={Hello} wrapper={"div"} />
        {repeatComponent(data, Hello)}
      </div>,
      document.getElementById('container')
    );
[/code]

[code]

    <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="container">
    </div>
[/code]


CC BY-SA 3.0
2017-03-26T05:14:56.690
33540
2017-03-26T05:14:56.690
8771
32713
answer