在3个元素之后有条件地添加一行:ReactJS

时间:2019-05-03 09:22:25

标签: javascript reactjs react-native

我想渲染几行,每行包含三列。这些列只有一个Card。我认为我可以这样做的方式是map遍历所有元素,并在row模数为0时创建一个index,并在row为模数的第三列时将其关闭行。我已经尝试过使用if-else语句和三元运算符。但是我不断收到语法错误。

render(){
  var { isLoaded, items } = this.state;

  if(!isLoaded) {
    return (<div> Fetching items </div>);
  }
  else {
    var results = items.results;
    return (
      <div className="App">
        <div className ="container">
        { result.map ((result, i) => {
          return(
            {i%3===0 ?
                <div className ="row mt-4">
                  <div key ={i} className="col-md-4">
                    <Card result={result}></Card> 
                  </div>
              :
                  <div key ={i} className="col-md-4">
                    <Card result={result}></Card> 
                  </div>);
              }
            {i%3===1 ?
                </div>
                :null}
              })}

        </div>
      </div>
    );
  }
}

使用这段代码,我在这一行中遇到错误

{i%3===0 ?

我该如何解决?

4 个答案:

答案 0 :(得分:1)

因为,您有一个未关闭的<div>标签,它是无效的JSX,因此,{的返回也意味着对象不是动态内容。

别忘了我们写JSX,而不是html。每个标签都需要正确关闭,因为它将转换为React.createElement(component/html tag, props, children)

要解决此问题,请先准备数组,然后再放置3个项目,只需将元素推入行数组中,如下所示:

renderRows() {
  let results = items.results;
  let finalArr = [], columns = [];

  result.forEach ((result, i) => {

    // prepare the array
    columns.push(
      <div key ={i} className="col-md-4">
        <Card result={result}></Card> 
      </div>
    );

    // after three items add a new row 
    if((i+1) % 3 === 0) {
      finalArr.push(<div className ="row mt-4">{columns}</div>);
      columns = [];
    }
  });
  return finalArr;
}

render(){
  var { isLoaded, items } = this.state;

  if(!isLoaded) {
    return (<div> Fetching items </div>);
  } else {
    return (
      <div className="App">
        <div className ="container">
          {this.renderRows()}
        </div>
      </div>
    );
  }
}

答案 1 :(得分:0)

您只是缺少一些右括号。

尝试一下

<div className ="row mt-4">
{ result.map ((result, i) => {
    return(
         <React.Fragment>
      {(i%3===0) ?
           <div key ={i} className="col-md-4">
           <Card result={result}></Card> 
           </div>
           :
           <div key ={i} className="col-md-4">
           <Card result={result}></Card> 
           </div>
        }
          </React.Fragment>
      )
   })}
</div>

根据您的代码,

{ result.map ((result, i) => {
        return(
          {i%3===0 ?
              <div className ="row mt-4">
                <div key ={i} className="col-md-4">
                  <Card result={result}></Card> 
                </div>
            :
                <div key ={i} className="col-md-4">
                  <Card result={result}></Card> 
                </div>); //You have added `);` which is cause of error. this means you are returning this much part only.

答案 2 :(得分:0)

以下是解决方法:

render() {
    const { isLoaded, items } = this.state;

    if (!isLoaded) {
      return (<div> Fetching items </div>);
    }

    const results = items.results;
    return (
      <div className="App">
        <div className="container">
          {results.map((result, i) => (
            <React.Fragment>
              {(i + 1) % 4 === 0 ?
                (<div className="row mt-4" key={`row-${i}`}>
                  <div key={i} className="col-md-4">
                    <Card result={result} />
                  </div>
                </div>) :
                (<div key={i} className="col-md-4">
                  <Card result={result} />
                </div>)}
              {i % 3 === 1 ? <div /> : null }
            </React.Fragment>
          ))}
        </div>
      </div>
    );
  }

我强烈建议您使用ESLint或linter在那时和那里查找并修复这些错误。看一下:https://medium.com/@RossWhitehouse/setting-up-eslint-in-react-c20015ef35f7。 Eslint将为您提供更好的缩进,匹配的括号,最佳实践等更多信息。设置了附加费之后,您就可以自己进行整理了。

编辑:

将项目分为四部分,并将它们放在一行以下:

class Application extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      isLoaded: true,
      items: {
        results: ["1", "2", "3", "4", "5", "6", "7", "8"]
      }
    };
  }

  render() {
    const { isLoaded, items } = this.state;

    if (!isLoaded) {
      return (<div> Fetching items </div>);
    }

    const results = items.results;
    // Group them into sets of 4.
    const grouped = results.reduce((acc, post, ind) => {
       var index = parseInt(ind / 4);
       acc[index]= acc[index] || [];
       acc[index].push(<div key={`colmn-${index}`} className="col-md-4">{results[ind]}</div>);
       return acc;
     }, []);
    return (
      <div className="App">
        <div className="container">
          {grouped.map((row, i) => {
          return <div className="row mt-4" key={`row-${i}`}>{row}</div>})}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<Application />, document.getElementById("retrospect-app"));
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet"/>
<div id="retrospect-app"></div>
	<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
	<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
	<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

答案 3 :(得分:0)

您会收到错误消息,因为您并不是每次都呈现一个有效元素-当“ i%3 === 0”解析为true时,它会丢失一个结束标记。

 <div className ="row mt-4">
     <div key ={i} className="col-md-4">
         <Card result={result}></Card> 
      </div>
 </div> // <-- this one

此外,您可以只渲染一个容器中的所有卡片,并将卡片的样式相应地设置为父容器的三分之一的宽度。

 <div className="container">
   {result.map((result, i) => {
     return (
       <div key={i} className="col-md-4"> // add styles for width 30%
         <Card result={result} />
       </div>
     );
   })}
 </div>

另一个想法是,您可以将数组简化为其他数组的存储桶,例如[[1,2,3],[4,5],而不是像[1,2,3,4,5]那样馈送数据,6]]并渲染它们。

  <div className="container">
    {result.map((row, i) => (
      <div key={i} className="row mt-4">
        {row.map((col, i) => (
          <div key={i} className="col-md-4">
            <Card result={col} />
          </div>
        ))}
      </div>
    ))}
  </div>

P.s。不要将索引用于元素键。使用独特的东西,例如卡的值或ID。