我整天都有一个问题让我疯狂。我的项目基本上是使用React Rails gem构建一个聊天机器人,具有顶级Alt容器,主要组件和子组件。
我在让子组件中的onClick
处理程序在特定情况下触发时遇到问题。
在React Rails中运行时,我无法获取onClick
组件的ExampleChildComponent
函数,并且如果组件正在使用Alt js存储的条件语句中呈现。
当使用Webpack托管时,该应用程序运行正常,但使用React-Rails gem,Babelify和Browserify我得到了上述问题。
我正在使用以下与React相关的技术:
我正在与Webpack和Rails并行开发。我在Webpack工作,然后切换到Rails,以确保一切正常。我的项目100%完美地使用Webpack,React热加载器和HTML Webpack插件,但在Rails运行时中断。
我有一个顶级组件,它将所有内容包装到Alt容器中。
import React from 'react';
import AltContainer from 'alt/AltContainer';
import ExampleStore from './stores/ExampleStore';
import ExampleActions from './actions/ExampleActions'
import ExampleComponent from './components/ExampleComponent';
export default class ChatContainer extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
ExampleStore.fetchSurvey();
}
render() {
return(
<AltContainer
stores={{ExampleStore: ExampleStore}}
actions={{ExampleActions: ExampleActions}}>
<ExampleComponent/>
</AltContainer>
);
}
}
在我的主ExampleComponent中,我有以下代码,根据我的Alt商店状态交换进出组件:
import React from 'react';
import ExampleChildComponent from './ExampleChildComponent';
export default class ExampleComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
const isReady = this.props.ExampleStore.isReady;
return <div>{isReady ? <ExampleChildComponent/>: 'Loading...'}</div>;
}
}
示例子组件类型将是以下FaceMood组件:
import React from 'react';
export default class ExampleChildComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick () {
console.log('Example child component clicked');
}
render() {
return(
<div onClick={this.handleClick}>
Example Child Component
</div>
);
}
}
这一切在Webpack中完全正常,但是在React-Rails中,单击ExampleChildComponent中的handleClick
时,<div>
函数没有被执行。
有趣的是,我设法将问题缩小到我的ExampleComponent
组件中的以下代码行:
return <div>{isReady ? <ExampleChildComponent/>: 'Loading...'}</div>;
现在如果我没有在ALL处引用this.props.ExampleStore.isReady
,那么onClick事件处理程序工作正常:
return <div><ExampleChildComponent/></div>
这当然不太理想,因为我希望我的Pane根据聊天机器人对话的当前进度显示不同的组件类型。
我非常关注我的智慧,所以我希望有些人可以帮助我!
使用Alt.js' async datasource methods设置道具this.props.ExampleStore.isReady
。它是一个javascript承诺,在完成数据提取后将isReady
标志设置为true。
以下是Flux操作的代码:
import alt from '../utils/Alt';
class ExampleActions {
fetchSurvey() {
this.dispatch();
}
updateSurvey(survey) {
this.dispatch(survey);
}
fetchSurveyFailed(errorMessage) {
this.dispatch(errorMessage);
}
}
export default alt.createActions(ExampleActions);
现在Flux商店的代码:
import alt from '../utils/Alt';
import ExampleActions from '../actions/ExampleActions';
import ExampleSource from '../sources/ExampleSource';
class ExampleStore {
constructor() {
this.isReady = false;
this.bindListeners({
handleFetchSurvey: ExampleActions.FETCH_SURVEY,
handleUpdateSurvey: ExampleActions.UPDATE_SURVEY,
handleFetchingSurveyFailed: ExampleActions.FETCH_SURVEY_FAILED
});
this.registerAsync(ExampleSource);
}
handleFetchSurvey() {
}
handleUpdateSurvey() {
this.isReady = true;
}
handleFetchingSurveyFailed(errorMessage) {
}
}
export default alt.createStore(ExampleStore, 'ExampleStore');
现在是flux数据源的代码:
import ExampleActions from '../actions/ExampleActions';
const MockQuestions = [
{
}
];
const ExampleSource = () => {
return {
fetchSurvey() {
return {
remote() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (true) {
resolve(MockQuestions);
} else {
reject('Fetch failed');
}
}, 500);
});
},
local() {
return null;
},
loading: ExampleActions.fetchSurvey,
success: ExampleActions.updateSurvey,
error: ExampleActions.fetchSurveyFailed
};
}
};
}
export default ExampleSource;
onClick()
函数也可以在react dev工具应用程序中看到,它只是不执行它!