如何使用react呈现分组列表

时间:2017-02-01 09:42:22

标签: javascript reactjs jsx

我试图根据在下面的代码段上的const元素按状态分组的对象数组来呈现列表。

我知道我可以在这里创建更小的组件,但我真的想让我的renderMethod工作。

根据这个jsbin,逻辑很好:

https://jsbin.com/cejiziyupa/edit?js,console

我无法弄清楚我在做什么和做反应和JSX。

有什么想法吗?

以下是我在codepen上的代码 - http://codepen.io/vinicius5581/pen/rjJRvM?editors=0011

组件:

class MyComponent extends React.Component{

  constructor(props){
    super(props)
    renderMethod().bind(this);
  }

  renderMethod(){
    const elements = [
      { "id": 1, "label": "element1", "status": "status1"},
      { "id": 2, "label": "element2","status": "status2"},
      {"id": 3, "label": "element3", "status": "status6"},
      { "id": 4, "label": "element3", "status": "status10"}
    ]

    const groups = [
      { "name": "group1", "status" : ["status1", "status2", "status3", "status4"] },
      { "name": "group2", "status" : ["status5", "status6", "status7", "status8"] },
      { "name": "group3", "status" : ["status9", "status10"] }
    ]


    return (
      groups.map((group) => {
        return(
          console.log(group.name);
          <h1>{group.name}</h1>
          elements.filter((element) => group.status.includes(element.status)).map((element) =>{
            return(
              console.log(element.id);
              <div>
                <h1>{element.label}</h1>
                <p>{element.status}</p>
              </div>
            )
          })
        )
      })
    )

  }


  render(){
    return(
      {this.renderMethod()}
    )  
  } 
}

ReactDOM.render(<MyComponent />, document.getElementById('root'));

HTML:

<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>

2 个答案:

答案 0 :(得分:0)

从顶部开始。您的codepen没有转换JSX,因此您最终在javascript中使用<div>标记,这会导致语法错误。此外,您的console.log语句导致语法错误,您无法在Javascript中执行return(x; y)

现在实际的反应组件问题如下:

  • 在构造函数中,您尝试将renderMethod函数绑定到this的上下文。但要做到这一点,你需要使用this.renderMethod否则它将寻找一个名为renderMethod的变量,它不存在。
  • 您正在调用函数的结果上的绑定,而不是函数本身。所以你立即执行该函数,返回一个反应对象并尝试绑定它。通过删除调用函数this.renderMethod().bind(this)成为this.renderMethod.bind(this)
  • 的括号来解决此问题
  • 在你的渲染函数中,你将renderMethod调用包装在JSX样式括号中,我不确定这是否有效,它可能,但是有必要使用它或标准括号(并且可以说,甚至一个单独的函数调用)。因此return ({this.renderMethod()})变为return this.renderMethod();
  • renderMethod的返回值是一个数组,当它需要是一个对象时。通常,您可以将其包装在一个简单的div中以解决问题。请记住,您正在创建的是SINGLE组件,而不是组件列表,从来没有理由返回数组。

现在由于开头所述的JSX问题,我无法让你的页面呈现,所以我在标准的React调用中重新创建了它。我添加了关键参数以消除警告。

class MyComponent extends React.Component{

  constructor (props) {
    super(props);
    this.renderMethod.bind(this);
  }

  renderMethod () {
    const elements = [
      { "id": 1, "label": "element1", "status": "status1" },
      { "id": 2, "label": "element2","status": "status2" },
      { "id": 3, "label": "element3", "status": "status6" },
      { "id": 4, "label": "element3", "status": "status10" }
    ];

    const groups = [
      { "name": "group1", "status" : ["status1", "status2", "status3", "status4"] },
      { "name": "group2", "status" : ["status5", "status6", "status7", "status8"] },
      { "name": "group3", "status" : ["status9", "status10"] }
    ];


    return React.createElement('div', {}, groups.map(
      group => elements.filter(element => group.status.includes(element.status)).map((element, index) => (
        React.createElement('div', { key: 'el_' + index }, [
          React.createElement('h1', { key: 'el_h1_' + index }, [element.label]),
          React.createElement('p', { key: 'el_p_' + index }, [element.status])
        ])
      ))
    ));
   }


   render () {
     return this.renderMethod();
   } 
 }

ReactDOM.render(React.createElement(MyComponent), document.getElementById('root'));

这相当于JSX

中的类似内容
return (
  <div>
    {groups.map(
      group => elements.filter(element => group.status.includes(element.status)).map((element, index) => (
        <div key={'el_' + index}>
          <h1>{element.label}</h1>
          <p>{element.status}</p>
        </div>
      ))
    )}
  </div>
);

我也不会进入你在那里做的所有数组迭代,但足以说,你不应该在渲染调用中做那么多工作。

答案 1 :(得分:0)

我发现你的代码中存在许多不正确的东西:

  1. render应返回一个元素,但在您的代码中,您将返回多个元素

  2. return声明不应该console.log。将其视为

  3. 不正确:

    return (a + b; console.log(a););
    

    正确:

    console.log(a);
    return (a + b);
    
    1. map应该返回单个根元素,但是您将返回多个元素。

    2. elements.filter应该在{}中,因为JS代码不是JSX。

    3. 更正代码:

          class MyComponent extends React.Component{
      
            constructor(props){
              super(props);
              this.renderMethod = this.renderMethod.bind(this);
            }
      
            renderMethod() {
              const elements = [
                { "id": 1, "label": "element1", "status": "status1"},
                { "id": 2, "label": "element2","status": "status2"},
                {"id": 3, "label": "element3", "status": "status6"},
                { "id": 4, "label": "element3", "status": "status10"}
              ];
      
              const groups = [
                { "name": "group1", "status" : ["status1", "status2", "status3", "status4"] },
                { "name": "group2", "status" : ["status5", "status6", "status7", "status8"] },
                { "name": "group3", "status" : ["status9", "status10"] }
              ];
      
      
              return (
                <div>
                  {groups.map(group => {
                    return(
                      <div>
                        <h1>{group.name}</h1>
                        {elements
                          .filter(element => group.status.includes(element.status))
                          .map(element => {
                            return(
                              <div>
                                <h1>{element.label}</h1>
                                <p>{element.status}</p>
                              </div>
                            )
                          })
                        }
                      </div>
                    )
                  })}
                </div>
              );
            }
      
      
            render() {
              return (
                <div>{ this.renderMethod() }</div>
              )
            }
          }