我正在使用react和redux来完成我当前的项目。我有一个按钮,每当用户点击它时,它首先调用服务器并加载一些数据,然后操纵一些dom元素的CSS。 这是我的代码:
var allClickableStories = document.getElementById("dummyClickStory" + this.props.story.id);
$(allClickableStories).click(function () {
if (!$("#" + this.id + " .expansion-handler").hasClass("show")) {
var storyId = this.id.replace("dummyClickStory", "");
thisRef.props.getStoryDetail(storyId, thisRef.props.channel);
$("#" + this.id + " .expansion-handler").addClass("show");
$("#" + this.id + " .cutline").addClass("show");
}
});
另外值得注意的是,componentDidMount中的上述代码确保首次渲染发生。但是,这并不能保证ajax调用(thisRef.props.getStoryDetail)在css操作之前发生,这正是我被困在的地方。发生了什么是ajax调用被发送然后css操作触发但是ajax调用可能会返回并且渲染将发生并再次隐藏被操纵的dom元素。一种简单的方法来修复它是在jquery ajax调用中将asynch设置为false但不是一个好的解决方案那么我怎样才能确保第一个ajax调用完成并渲染发生然后进行css操作?
此处仅有更多信息,请参阅Action和reducer中的代码:
动作:
export function getStoryDetail(storyId,channel){
return dispatch => {
$.ajax({
url: "http://localhost:3003/json5.txt",
dataType: 'json',
cache: false,
success: function(data) {
var storyDetatil=[];
for (var key in data) {
storyDetatil.push(data[key]);
}
var storyDetailObj={"storyArray":storyDetatil,"storyId":storyId, "channel":channel};
dispatch({
type: "STORY_EXPANSION",
payload: storyDetailObj
});
}.bind(this)
});
};
}
减速机:
case "STORY_EXPANSION":
var tempStateExpansion = state.slice();
if (action.payload.storyId > -1 && state[0].channel !=undefined) {
for(var i=0;i<state.length;i++){
if(state[i].channel.toLowerCase()===action.payload.channel.toLowerCase()){
for(var j=0;j<state[i].storiesSnippet.length;j++){
if(action.payload.storyId===state[i].storiesSnippet[j].id){
tempStateExpansion[i].storiesSnippet[j]=action.payload.storyArray[0];
break;
}
}
break;
}
}
}
else{
tempStateExpansion[0].storiesSnippet[0]=action.payload.storyArray[0];
}
state=tempStateExpansion;
break;
答案 0 :(得分:0)
简而言之,你不能用React做到这一点。你正在使用jQuery来操作DOM,这基本上是与React相反的方法。 React为你操纵DOM。
你应该做的是拥有一个组件(你可以看一下内联样式:https://facebook.github.io/react/docs/dom-elements.html),它将根据更新的状态重新渲染。
connect
和mapStateToProps
更新了在满足ajax请求时应该更改的组件的道具。我建议在这里运行带有redux和React的TODO List示例:http://redux.js.org/docs/basics/UsageWithReact.html。您的Redux使用情况看起来没问题,但React是有问题的。
以下是使用React组件的示例,该组件将根据redux状态的data
属性重新渲染。它假定您将拥有一个应用程序范围的CSS,其中包含foo
和bar
CSS类的定义。
import React from 'react';
import { connect } from 'react-redux';
class Example extends React.Component {
render() {
const { data } = this.props;
// If data is present (render a div using CSS from class foo)
// and put the data in the div asuming it's a string
if (data) {
return <div className='foo'>{ data }</div>;
}
// If data is not present (render a div using CSS from class bar)
// Display No Content
return <div className='bar'>No Content</div>;
}
}
// Data is an object, but not required as initially it will be undefined
Example.propTypes = {
data: React.PropTypes.object
};
// Map redux state to react props
const mapStateToProps = state => ({
data: state.data
});
// Connect to redux store helper using our mapping function
export default connect(mapStateToProps)(Example);