我们需要在window.onresize
和window.onscroll
上的组件层次结构的不同部分执行与DOM元素相关的一些操作:
1)调整大小到移动分辨率时移动元素
2)滚动时更改类和样式。
问题是元素处于React组件层次结构的不同级别,即嵌套在不同的组件中。因此,如果我理解正确,我就无法使用refs
来访问DOM节点。
我有:
{someCondition ? <FirstComponent/>: <SecondComponent/>}
someCondition
可以由于用户UI操作而改变,或者从页面加载开始就可以改变。
我已经尝试在我的componentDidMount
上使用componentDidUpdate
和FirstComponent
,但发现componentDidMount
仅在someCondition
从一开始就为真时触发,componentDidUpdate
确实在someCondition
发生更改时触发,但此时所需的DOM元素(包含在组件中)尚未就绪,document.getElementById
失败。
添加window.requestAnimationFrame
没有帮助。
我想在React中应该有一个可行的方法吗?
也许React.findDomNode
?
谢谢。
答案 0 :(得分:4)
你所描述的是React的对立面。这是我在使用基于命令式jQuery / Dojo的框架时所期望的方法。
使用React,您正在开发知道如何将状态转换为呈现HTML的功能组件,并且您需要以不同方式处理问题。
对于您的问题,您的window.onresize
和window.onscroll
回调应该不尝试操纵React DOM元素。相反,它应该只更新状态并让React重新渲染。您的React组件应该接收此状态并相应地进行渲染。
这是一个简单的示例,其中主应用程序侦听这些事件并更新其状态,从而触发重新呈现。该应用程序将状态作为道具传递给孩子们。孩子们使用道具有条件地改变他们的css类名。他们也可以轻松渲染不同的html或内联样式。
const Component2 = ({someCondition2}) => {
const className = someCondition2 ? "foo" : "bar";
return <div className={className}>Hello</div>;
};
const Component1 = ({someCondition1, someCondition2}) => {
const className = someCondition1 ? "A" : "B";
return (
<div className={className}>
<Component2 someCondition2={someCondition2} />
</div>
);
};
class App extends React.Component {
state = {
someCondition: false,
someCondition2: true,
};
componentDidMount() {
window.onresize = ev => {
const someCondition = ev.xxx;
// re-render with the new state
this.setState({ someCondition });
};
window.onscroll = ev => {
const someCondition2 = ev.xxx;
this.setState({ someCondition2 });
};
}
render() {
const {someCondition, someCondition2} = this.state;
return (
<Component1
someCondition1={someCondition1}
someCondition2={someCondition2} />
);
}
}
React.render(<App />, document.getElementById("container"));