【问题标题】:Return JSX from function从函数返回 JSX
【发布时间】:2018-05-19 09:18:03
【问题描述】:

我有一个组件需要检查多个选项并根据这些选项返回。因此,我创建了一个在我的组件返回语句中调用的外部函数,以确定将返回的格式:

render() {
    const { policy } = this.props;
    let deployment = policy.Deployment;
    let value = policy.value;
    let policyLegend = deployment.policyLegend;
    let policyObj = this.valueToPolicy(policyLegend, value);
    console.log(policyObj);
    if(policy.name == "SP4") {
      policyLegend[1].values = this.formatSp4Firmware(policyLegend[1]);
      return (
        <div>
          <Form onSubmit={ (event) => this.handleSubmit(event, this.props) }>
            {
              policyLegend.map((policy) => {
                return (
                  <div key={ policy.id }>
                    <h3>{ policy.displayName }</h3>
                    { this.renderSp4Policies(policy) }
                  </div>
                );
              })
            }
            <Button name={ 'Submit' } type='submit'>Submit</Button>
            <Button onClick={ this.props.onCancel }>Cancel</Button>
          </Form>
        </div>
      )
    } 
  }
<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>

renderSp4Policies(policy) {
    if(policy.displayName == "Firmware Options") {
      let firmwareDropdownNames = this.formatFirmawareDropdownNames(policy);
      let toggles = policy.values[0][Object.keys(policy.values[0])];
      let toggleOptions = []
      Object.keys(toggles).map(toggle => {
      	if(typeof(toggles[toggle]) == "boolean"){
          var obj = {};
          obj[toggle] = toggles[toggle];
      		toggleOptions.push(obj);
        }
      })
      return (
        toggleOptions.map(toggleOption => {
          let toggleName = Object.keys(toggleOption).toString();
          return (
            <Form.Field key={ toggleName }>
              <label>{ toggleName }</label>
              <Checkbox toggle />
            </Form.Field>
          )
        })
      )
    } else {
        return (
          policy.values.map(value => {
            return(
              <Form.Field key={ value.name }>
                <label>{ value.displayName || value.name }</label>
                <Checkbox toggle />
              </Form.Field>
            )
          }
        )
      )
    }
  }
<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>

编辑

我已经应用了一些给出的答案并取得了一定的成功。

renderSp4Policies 内显示else 语句中返回的内容,但开头的if(policy.displayName == "Firmware Options") 不返回任何内容。

感谢所有建议,提前感谢您!

【问题讨论】:

    标签: javascript reactjs components jsx


    【解决方案1】:

    我经常遇到这种情况,直到现在才意识到为什么会这样。在您的renderSp4Policies 函数中,您正在通过第二行具有Object.keys(toggles).forEach(toggle =&gt; { 的键进行映射。在该块内,您正在返回元素,并且您正在运行的指令正在跟踪它并生成一个数组。完成后,您不会对数组做任何事情,因此您必须添加 return 语句,以便函数返回生成的 JSX 元素数组:

    return Object.keys(toggles).map(toggle => {
        return(
          <Form.Field key={ toggle }>
            <label> { toggle } </label>
            <Checkbox toggle />
          </Form.Field>
        );
      });
    

    正如 Sag1v 所说,具有policy.values.map 的行,您不会在该循环内返回。所以你必须改变:

    policy.values.map(value => (
      return (
        <Form.Field key={ value.name }>
          <label>{ value.displayName || value.name }</label>
          <Checkbox toggle />
        </Form.Field>
      );
    ));
    

    编辑

    在聊天讨论之后,我想更新我的答案以反映适当的变化。

    第一个 Object.keys 调用决定了哪些键应该被保存,哪些键不应该在每次迭代后返回新数据,所以它只是创建一个空数组。 forEach 也被使用了,但这并没有返回一个新的数组。在将 forEach 更改为 map 并添加一些返回语句后,它将创建一个新数组,以便接下来的第二个循环能够运行:

    var toggleOptions = Object.keys(toggles).map(toggle => {
      if (typeof (toggles[toggle]) !== "boolean") {
        return delete toggles[toggle];
      }
      return toggles[toggle];
    })
    

    【讨论】:

    • 感谢您的帮助,但是应用您的更改后,Object.keys(toggles).forEach(toggle =&gt; { return( &lt;Form.Field key={ toggle }&gt; &lt;label&gt; { toggle } &lt;/label&gt; &lt;Checkbox toggle /&gt; &lt;/Form.Field&gt; ); }); 仍然没有返回任何内容
    • 如果您将Object.keys 的结果分配给一个变量并console.log 它,您在日志中看到JSX 元素了吗?
    【解决方案2】:

    似乎很多人已经很好地帮助您解决了您的问题并详细解释了它。但是不要忘记遵循 React 引入的基于组件的架构的新概念。因此,作为最佳实践,您可以这样编写:

    import React, {Component} from "react";
    
    import Sp4Policies from "./sp4Policies";
    
    class MyComponent extends Component {
      render() {
        const { policy } = this.props;
        let deployment = policy.Deployment;
        let value = policy.value;
        let policyLegend = deployment.policyLegend;
        let policyObj = this.valueToPolicy(policyLegend, value);
        console.log(policyObj);
        if(policy.name == "SP4") {
          policyLegend[1].values = this.formatSp4Firmware(policyLegend[1]);
          return (
            <div>
              <Form onSubmit={ (event) => this.handleSubmit(event, this.props) }>
                {
                  policyLegend.map((policy) => {
                    return (
                      <div key={ policy.id }>
                        <h3>{ policy.displayName }</h3>
                        <Sp4Policies policy={policy} />
                      </div>
                    );
                  })
                }
                <Button name={ 'Submit' } type='submit'>Submit</Button>
                <Button onClick={ this.props.onCancel }>Cancel</Button>
              </Form>
            </div>
          )
        } 
      }
    }
    

    还有一个单独的文件:

    import React, {Component} from "react";
    
    class Sp4Policies extends Component {
      render() {
         const policy = this.props.policy;
    
         if (policy.displayName == "Firmware Options") {
           return (
             policy.values.map(value => (
               <Form.Field key={ value.name }>
                 <label>{ value.displayName || value.name }</label>
                 <Checkbox toggle />
               </Form.Field>
            ))
           );
         }
    
         return (
           let toggles = policy.values[0][Object.keys(policy.values[0])];
           Object.keys(toggles).forEach(toggle => {
             if(typeof(toggles[toggle]) !== "boolean"){
                 delete toggles[toggle];
             }
           })
           Object.keys(toggles).map(toggle => {
             return(
               <Form.Field key={ toggle }>
                 <label> { toggle } </label>
                 <Checkbox toggle />
               </Form.Field>
             );
           })
         );
      }
    }
    
    export default Sp4Policies;
    

    这使您的代码干净,并确保组件之间的关注点分离。当然,您仍然可以进一步将其分开。

    【讨论】:

      【解决方案3】:

      您的 map 函数没有返回任何内容:

      policy.values.map(value => {
                  <Form.Field key={ value.name }>
                    <label>{ value.displayName || value.name }</label>
                    <Checkbox toggle />
                  </Form.Field>
                } 
      

      当使用箭头功能块{} 时,您应该添加一个显式的return 语句:

      policy.values.map(value => {
                  return(<Form.Field key={ value.name }>
                    <label>{ value.displayName || value.name }</label>
                    <Checkbox toggle />
                  </Form.Field>)
                }
      

      编辑
      作为您评论的后续行动。

      至于第一个if 语句,不要使用forEach,使用map。与您在第二个 if 语句中所做的相同(不要忘记 return!)

      renderSp4Policies(policy) {
        if (policy.displayName == "Firmware Options") {
          let toggles = policy.values[0][Object.keys(policy.values[0])];
          Object.keys(toggles).forEach(toggle => {
            if (typeof (toggles[toggle]) !== "boolean") {
              delete toggles[toggle];
            }
          })
          return (
            Object.keys(toggles).map(toggle => {
              return (
                <Form.Field key={toggle}>
                  <label> {toggle} </label>
                  <Checkbox toggle />
                </Form.Field>
              );
            })
          )
        } else {
          return (
            policy.values.map(value => {
              <Form.Field key={value.name}>
                <label>{value.displayName || value.name}</label>
                <Checkbox toggle />
              </Form.Field>
            })
          );
        }
      }
      

      【讨论】:

      • 谢谢!这修复了else 语句的返回,但我仍然遇到从第一个if 语句返回的问题
      • 你的意思是这个语句` if(policy.name == "SP4") ` ?
      • 请注意,您没有 else 用于此 if 语句 ` if(policy.name == "SP4") `
      • 技术上是的,但特别是 { this.renderSp4Policies(policy) } 函数调用中的 if(policy.displayName == "Firmware Options")
      • 不要使用 forEach,它不会返回新数组。在这里也使用map
      【解决方案4】:

      只需用地图箭头函数返回来改变这个函数。

      renderSp4Policies(policy) {
          if(policy.displayName == "Firmware Options") {
            let toggles = policy.values[0][Object.keys(policy.values[0])];
            Object.keys(toggles).forEach(toggle => {
              if(typeof(toggles[toggle]) !== "boolean"){
                  delete toggles[toggle];
              }
            })
            Object.keys(toggles).forEach(toggle => {
              return(
                <Form.Field key={ toggle }>
                  <label> { toggle } </label>
                  <Checkbox toggle />
                </Form.Field>
              );
            })
          } else {
              return (
                policy.values.map(value => (
                  <Form.Field key={ value.name }>
                    <label>{ value.displayName || value.name }</label>
                    <Checkbox toggle />
                  </Form.Field>
                ))
              );
            }
        }
      

      【讨论】:

        猜你喜欢
        • 2018-03-10
        • 1970-01-01
        • 2021-05-14
        • 1970-01-01
        • 1970-01-01
        • 2017-07-24
        • 1970-01-01
        • 1970-01-01
        • 2019-03-16
        相关资源
        最近更新 更多