【问题标题】:How to deal with missing fields in react.js如何处理 react.js 中的缺失字段
【发布时间】:2014-12-21 23:47:14
【问题描述】:

假设有一个用 react.js 编写的应用程序。它通过 rest api 获取单个 json 并将一些属性传递给子组件。

什么是处理可能缺少的 json 属性和东西的正确方法?如果有道具,我可能应该检查每个组件,并用适当的结构填充状态但填充空数据,如下所示:

var SomeComponent = React.createClass({
getInitialState: function() {
  return {
    someNestedStructure: {
      foo: {
        bar: null,
        baz: null
      },
      morenested: {
        something: '',
        andEvenMoreNested: {
            somethingb: ''
        }
      },
      somedata: {
        id: null
      },
      somedataaa: {
      }
    }
  }
},
componentDidMount: function() {
  //call rest api and set new state depending on what is inside json
  //check every required field to pass to children compoents
},
render: function() {
  return (
    <div>
        <ComponentUsingNEsteStructure data={this.state.someNestedStructure.moreNested}/>
        <ComponentThatNeedsEverythign data={this.state.someNestedStructure} />
        <SomeOtherComponent some={this.sate.somedataaa} />
    </div>
  );
}
});

但我猜它会在代码中生成很多与 json 相关的结构和很多 if。

感谢您的帮助!

【问题讨论】:

    标签: javascript json rest design-patterns reactjs


    【解决方案1】:

    您可以通过使用 getDefaultProps 为每个组件的 props 分配默认值来解决缺失值的问题,从而避免在顶层出现大型嵌套对象。您可以将 REST API 访问权限移至父级,并通过其 props 将结果传递给子级(不过,您必须使用父级的状态作为触发器,以便在获得 AJAX 响应时重新渲染子级)。

    【讨论】:

      【解决方案2】:

      这不是 React 特有的。你想要的是深度扩展。这在 npm 上可用 deep-extend

      用法是这样的:

      var defaultsForThing = {
        foo: '',
        bar: {
          baz: true,
          quux: null
        }
      };
      
      // make a defaulting function
      var defaultThing = deepExtend.bind(null, defaultsForThing);
      
      // fetch some data which might be missing fields
      $.getJSON('/api', function(data){
        var fixed = defaultThing(data);
        doSomethingWith(fixed);
      });
      

      这里是 deepExtend 函数(但更喜欢linked to module

      var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) {
          if (arguments.length < 1 || typeof arguments[0] !== 'object') {
              return false;
          }
      
          if (arguments.length < 2) return arguments[0];
      
          var target = arguments[0];
      
          // convert arguments to array and cut off target object
          var args = Array.prototype.slice.call(arguments, 1);
      
          var key, val, src, clone, tmpBuf;
      
          args.forEach(function (obj) {
              if (typeof obj !== 'object') return;
      
              for (key in obj) {
                  if ( ! (key in obj)) continue;
      
                  src = target[key];
                  val = obj[key];
      
                  if (val === target) continue;
      
                  if (typeof val !== 'object' || val === null) {
                      target[key] = val;
                      continue;
                  } else if (val instanceof Buffer) {
                      tmpBuf = new Buffer(val.length);
                      val.copy(tmpBuf);
                      target[key] = tmpBuf;
                      continue;
                  } else if (val instanceof Date) {
                      target[key] = new Date(val.getTime());
                      continue;
                  } else if (val instanceof RegExp) {
                      target[key] = new RegExp(val);
                      continue;
                  }
      
                  if (typeof src !== 'object' || src === null) {
                      clone = (Array.isArray(val)) ? [] : {};
                      target[key] = deepExtend(clone, val);
                      continue;
                  }
      
                  if (Array.isArray(val)) {
                      clone = (Array.isArray(src)) ? src : [];
                  } else {
                      clone = (!Array.isArray(src)) ? src : {};
                  }
      
                  target[key] = deepExtend(clone, val);
              }
          });
      
          return target;
      }
      

      我可能会在该函数中更改的一件事是它不能很好地满足这种情况:

      var defaults = {
        a: [{b: 0, c: 0}]
      };
      
      var obj = {
        a: [{b: 1}, {b: 2}, {c: 3}]
      };
      
      deepExtend(defaults, obj);
      

      出于修复 json 响应的目的,您希望得到以下结果,但这在技术上并不是一个深度默认值(它是模式强制)。

      {
        a: [{b: 1, c: 0}, {b: 2, c: 0}, {c: 3, b: 0}]
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-29
        • 2015-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-03
        • 2018-06-23
        相关资源
        最近更新 更多