簡體   English   中英

設置兒童的內聯樣式

[英]Set inline style of children

我正在嘗試為React中的孩子設置一些內聯樣式。 我有這個實際工作,有點:

var App = React.createClass({
  render: function() {
    var children = React.Children.map(this.props.children, function(child, i) {
      child.props.style.width = '100px'
    })
    return (
      <div>{children}</div>
    )
  }
})

但是,如果我嘗試在狀態更改時更改樣式,則樣式將保持不變。 嘗試類似這樣的操作時,您可以輕松地看到這一點:(小提琴: http : //jsfiddle.net/9UvWL/

var World = React.createClass({
    getInitialState: function() {
        return { width: 0 }
    },
    componentDidMount: function() {
        this.setState({ width: 100 })
    },
    componentDidUpdate: function() {
        console.log(this.getDOMNode().innerHTML);
    },
    render: function() {
        var width
        var children = React.Children.map(this.props.children, function(child, i) {
            width = i*this.state.width
            console.log('Setting width: '+width);
            child.props.style = {width: (i*this.state.width)+'px'}
            return child
        }, this)
        return <div>{children}</div>
    }
 })

var Hello = React.createClass({
    render: function() {
        return (
            <World>
                <div>1</div>
                <div>1</div>
            </World>
        )
    }
})

React.renderComponent(<Hello />, document.body);

它將記錄寬度已更改,但是props.style無法正常工作。 並且使用child.setProps()會引發“不變違規:replaceProps(...):只能更新已安裝的組件。”。 是否有另一種“內向方式”將內聯樣式更改為兒童?

您正在直接修改每個孩子的props對象,這繞過了React更新機制的一部分。 我們將很快使這成為不可能。

在這種情況下,您想在World組件的render函數中使用cloneWithProps

var children = React.Children.map(this.props.children, function(child, i) {
    width = i*this.state.width;
    console.log('Setting width: '+width);
    return React.addons.cloneWithProps(child, {style: {width: width + 'px'}})
}, this)
return <div>{children}</div>

cloneWithProps創建該組件的新副本,並合並其他道具。 您應該使用此模式來確保為React提供了它需要知道何時更新的所有提示。

這是您的示例工作: http : //jsfiddle.net/zpao/Tc5Qd/

在“只能更新已安裝的組件”檢查之后,還有另一個更具描述性的錯誤消息

  invariant(
    this._mountDepth === 0,
    'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
    'component with a parent. This is an anti-pattern since props will ' +
    'get reactively updated when rendered. Instead, change the owner\'s ' +
    '`render` method to pass the correct value as props to the component ' +
    'where it is created.'
  );

邏輯來自與更新DOM節點不同的角度。 當需要更改DOM節點時,通常的方法是獲取對DOM節點的引用,然后設置其屬性。 使用React,渲染方法不會更新特定的節點,而只是返回具有正確屬性集的新React組件,然后后端代碼確定要更新的DOM節點。

如果在正常的DOM代碼中錯誤地顯示了某些內容,則很難知道問題出在哪里,因為任何代碼都可以更新DOM節點。

當代碼像React中一樣安排到渲染方法中時,渲染方法始終采用this.propsthis.state並返回完整的,完全渲染的組件。 然后,如果無法正確渲染某些內容,則始終可以在render方法中查找問題,因為這是唯一發生渲染的地方。 (而且無論是第一個渲染還是第二個渲染,這都有效,因此在第一次渲染組件和更新組件之間不需要有區別。)

因此,解決您正在描述的問題的方法是將有關渲染div的邏輯轉移到創建div的render方法中,而不是轉移到其他組件的render方法中。 像這樣:

var World = React.createClass({
    render: function() {
        return <div>{this.props.children}</div>;
    }
 });

var Hello = React.createClass({
    getInitialState: function() {
        return { width: 0 };
    },
    componentDidMount: function() {
        this.setState({ width: 100 });
    },
    render: function() {
        var children = ["a", "b", "c"].map(function(content, i) {
            return (
                <div style={{ width: i * this.state.width }}>
                    {content}
                </div>
            );
        }, this);

        return (
            <World>
                {children}
            </World>
        )
    }
});

React.renderComponent(<Hello />, document.body);

http://jsfiddle.net/kN4DV/2/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM