反应:安装后如何从DOM中读取? [英] React: How to read from the DOM after mount?
本文介绍了反应:安装后如何从DOM中读取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在我的React组件中,我需要从DOM中读取数据,以便在以后的应用程序中正常工作。我需要将数据持久化为状态,并通过调度操作通过Flux发送数据。
In my React component, I need to read data from the DOM when it's available for later parts of my application to work. I need to persist the data into state, as well as send it through Flux by dispatching an action. Is there a best practice for doing this?
更具体地说,在至少两种情况下,我需要DOM中的数据:
To be more specific, I need the data from the DOM in at least two cases:
- 视觉上是即时的,因为用户首先看到的应该是正确的,这涉及到基于从DOM读取的数据的计算。
- 稍后使用的数据(例如用户移动鼠标),但基于初始DOM状态。
请考虑以下因素:
- 我需要从DOM中读取并保存数据。该DOM在
componentDidMount
中可用,但是我不能在componentDidMount
中调度动作,因为这会发生在调度过程中调度的错误。出于这个原因,在component * mount
中调度是React的反模式。 - 通常的解决方法是将分派放入
setTimeout(...,0)
调用中的componentDidMount
中。 我想避免这种情况,因为它看起来像是一种绕过Flux错误的黑客工具。如果确实没有更好的答案,我会接受,但是很不情愿。 - 不要以不要读DOM来回答这个问题。与我的要求有关。我知道这会将我的应用程序与DOM结合在一起,而且我知道这是不需要的。同样,我要问的问题与是否应使用此方法无关。
- I need to read from the DOM and save the data. This DOM is available in
componentDidMount
, however I cannot dispatch actions incomponentDidMount
because this will case a dispatch during a dispatch error. Dispatching incomponent*mount
is an anti-pattern in React for this reason. - The usual workaround (hack) for the above is to put the dispatch inside
componentDidMount
in asetTimeout( ..., 0 )
call. I want to avoid this as it seems purely like a hack to bypass Flux's errors. If there truly is no better answer I will accept it, but reluctantly. - Don't answer this question with don't read from the DOM. That's not related to what I'm asking. I know this couples my app to the DOM, and I know it's not desired. Again, the question I'm asking is unrelated to whether or not I should be using this method.
推荐答案
这是我在回流中使用的模式。
Here is the pattern I use in reflux.
export default class AppCtrl extends AppCtrlRender {
constructor() {
super();
this.state = getAllState();
}
componentDidMount = () => {
// console.log('AppCtrl componentDidMount');
this.unsubscribeApp = AppStore.listen(this.appStoreDidChange);
this.unsubscribeGS = GenusSpeciesStore.listen(this.gsStoreDidChange);
Actions.setWindowDefaults(window);
}
componentWillUnmount = () => { this.unsubscribeApp(); this.unsubscribeGS(); }
appStoreDidChange = () => { this.setState(getAppState()); }
gsStoreDidChange = () => { this.setState(getGsState()); }
shouldComponentUpdate = (nextProps, nextState) => {
return nextState.appStoreChanged && nextState.gsStoreChanged;
}
}
在app.store.js
In app.store.js
function _windowDefaults(window) {
setHoverValues();
let deviceTyped = 'mobile';
let navPlatform = window.navigator.platform;
switch (navPlatform) {
case 'MacIntel':
case 'Linux x86_64':
case 'Win32': deviceTyped = 'desktop'; break;
}
//deviceTyped = 'mobile';
_appState.deviceType = deviceTyped;
_appState.smallMobile = (deviceTyped == 'mobile' && window.screen.width < 541);
//_appState.smallMobile = (deviceTyped == 'mobile');
if (deviceTyped == 'desktop') {
let theHeight = Math.floor(((window.innerHeight - 95) * .67));
// console.log('_windowDefaults theHeight: ', theHeight);
_appState.commentMaxWidth = theHeight;
_appState.is4k = (window.screen.width > 2560);
Actions.apiGetPicList();
} else {
React.initializeTouchEvents(true);
_bodyStyle = {
color: "white",
height: '100%',
margin: '0',
overflow: 'hidden'
};
AppStore.trigger();
}
}
这篇关于反应:安装后如何从DOM中读取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文