如何正确传递具有扩展属性的嵌套属性? (JSX)

Posted

技术标签:

【中文标题】如何正确传递具有扩展属性的嵌套属性? (JSX)【英文标题】:How to pass nested properties with spread attributes correctly? (JSX) 【发布时间】:2016-07-15 21:39:03 【问题描述】:

#1

你好。 我有代码:

class Component extends React.Component 
    render() 
        this.props.nested.prop = this.props.parse.nested.prop;
        return <div>Component</div>;
    
    componentDidMount() 
        console.log(this.props.nested.prop);
    

Component.defaultProps = 
    nested: 
        prop: "default",
    ,
;

const obj1 = 
    nested: 
        prop: "obj1",
    ,
;
const obj2 = 
    nested: 
        prop: "obj2",
    ,
;

class Application extends React.Component 
    render() 
        return (
            <div>
                <Component parse=obj1 />
                <Component parse=obj2 />
            </div>
        );
    


React.render(<Application />, document.getElementById("app"));
// console output:
// "obj2"
// "obj2"

为什么我会为 2 个单独的组件获取 1 个变量引用,而不是为每个组件获取 2 个 nested.prop 实例? 为什么 this.props 在安装后只保存组件所有实例的最后设置值?这是正常行为吗? 我认为正确的行为是为不同的实例设置不同的属性值。

附:我已经测试了这段代码here。

#2

jimfb 已回答: "You are mutating the default prop that was passed in. The line this.props.nested.prop = this.props.parse.nested.prop; is illegal."

我的下一个问题: How to pass nested properties without a manual mutation of props?

例如:

Component.defaultProps = 
    nested: 
        prop1: "default",
        prop2: "default",
    ,
;

const props = 
    nested: 
        prop1: "value",
    ,
;

let component = <Component ...props />;

上面的 JSX 扩展属性功能的代码指南只是覆盖 props.nested 并且我失去了默认的嵌套属性。但这不是我需要的。 在 JSX 传播属性解析阶段如何实现嵌套对象的递归遍历? 或者这种情况有一些有用的模式吗?

【问题讨论】:

请在这里提出一个完全合格的问题,因为链接可能会失效。 以下是如何在 SO 上提出好问题的提示:***.com/help/how-to-ask “如何传递嵌套属性” foo(a.nested.property) ? 好的。稍后我将在家中使用我的电脑。 我不明白你想用你的代码实现什么。为什么要尝试将道具存储在其他道具中?以后你想怎么处理? 【参考方案1】:

这其实是个好问题!

简短的回答:您不能使用扩展运算符进行深度合并 - 它只能进行浅层合并。 但是你当然可以编写函数来遍历对象并实现深度合并。

这实际上给你留下了 3 个选择:

1) 只是不要进行深度合并。如果你有 2 级嵌套对象,你可以做这样简单的事情:

const newNested = ...oldProps.nested, ...newProps.nested ;
const finalProps =  ...oldProps, nested: newNested ;

浅合并强制明确说你将拥有嵌套属性的新价值。这是一件好事,因为它使您的代码显而易见。 您也可以尝试可运行的示例here。

2) 您可以将库用于不可变结构。 F.e. immutable.js。有了它,您的代码看起来会非常相似。

const oldProps = Immutable.fromJS(
  nested:
  
    prop1: "OldValue1",
    prop2: "OldValue2",
  
);

const newProps = Immutable.fromJS(
  nested:
  
    prop1: "NewValue1",
  
);

const finalProps = oldProps.updateIn(['nested'], (oldNested)=>
  oldNested.merge(newProps.get('nested'))
)

3) 您可以使用深度合并:在 npm 中找到一些实现或自己编写 你会得到这样的代码(再次以 immutable.js 为例):

const finalProps = oldProps.mergeDeep(newProps);

在某些情况下你可能想要这个,但是这样的代码使更新操作隐式,它会引发很多问题,这些问题在here

【讨论】:

以上是关于如何正确传递具有扩展属性的嵌套属性? (JSX)的主要内容,如果未能解决你的问题,请参考以下文章

如何向 TypeScript/JSX 中的现有 HTML 元素添加属性?

React JSX 选择性地将属性传递给组件

如何在 TypeScript 中键入这个“as”JSX 属性?

将对象道具作为 JSX 属性而不是对象传递

具有不同属性传递动态表达式的IQueryable扩展方法

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件