在React.js中的组件之间传递Ajax/服务数据
Passing Ajax/service data between components in React.js
我正在尝试传递在React应用程序的一个组件中接收的数据。成功后,我将接收到的数据并设置状态,然后尝试将该数据作为下一个组件的属性进行传递。一旦进入第二个组件,我需要通过this.state
访问传递的数据,以便稍后更改该组件中的状态。在从服务接收数据之前,我似乎遇到了DOM呈现的问题。我尝试在<List data={this.state.data}/>
中传递一个已经加载的值数组来代替this.state.data
,它似乎执行得很好。如何确保在呈现DOM之前已经从服务接收到数据,以便将数据一直传递到每个组件。
EDIT:添加了List元素的完整实现,因此解释了这个.state 的使用
这基本上就是我要做的:
var Box = React.createClass({
getInitialState: function() {
return {data: []};
},
loadTodosFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'GET',
cache: false,
success: function(dataResponse) {
this.setState({data: dataResponse});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.loadFromServer();
},
render: function() {
return (<List data={this.state.data}/>);
}
});
var List = React.createClass({
getInitialState: function() {
return {data: this.props.data};
},
dragStart: function(e) {
this.dragged = e.currentTarget;
e.dataTransfer.effectAllowed = 'move';
// Firefox requires dataTransfer data to be set
e.dataTransfer.setData("text/html", e.currentTarget);
},
dragEnd: function(e) {
this.dragged.style.display = "block";
this.dragged.parentNode.removeChild(placeholder);
// Update data
var data = this.state.data;
var from = Number(this.dragged.dataset.id);
var to = Number(this.over.dataset.id);
if(from < to) to--;
if(this.nodePlacement == "after") to++;
data.splice(to, 0, data.splice(from, 1)[0]);
this.setState({data: data});
},
dragOver: function(e) {
e.preventDefault();
this.dragged.style.display = "none";
if(e.target.className == "placeholder") return;
this.over = e.target;
// Inside the dragOver method
var relY = e.clientY - this.over.offsetTop;
var height = this.over.offsetHeight / 2;
var parent = e.target.parentNode;
if(relY > height) {
this.nodePlacement = "after";
parent.insertBefore(placeholder, e.target.nextElementSibling);
}
else if(relY < height) {
this.nodePlacement = "before"
parent.insertBefore(placeholder, e.target);
}
},
render: function() {
var results = this.state.data;
return (
<ul>
{
results.map(function(result, i) {
return (
<li key={i}>{result}</li>
)
})
}
</ul>
);
}
});
ReactDOM.render(
<Box url="/api/comments"/>, document.getElementById('content')
);
组件加载之后的数据加载没有呈现数据的原因是List.render函数中的这一行:
var results = this.state.data;
从本质上讲,您已经制作了原始道具的副本,并使用getInitialState方法将它们分配给List组件中的状态。在那之后,你的状态和道具就脱钩了。这意味着,如果List组件上的props.data发生了更改,则状态不知道它,因此不会重新渲染任何内容。
因此,不要使用state来初始化结果变量,而是使用props。
var results = this.props.data
以下是它的样子:
var List = React.createClass({
render: function() {
var results = this.props.data;
return (
<ul>
{
results.map(function(result, i) {
return (
<li key={i}>{result}</li>
)
})
}
</ul>
);
}
});
现在,只要数据发生变化,道具就会得到更新,最终结果会被重新渲染。
更新以解决OP的意见:
如果您希望更新列表的状态,但希望在父级的道具每次更改时都得到通知,那么您希望使用componentWillReceiveProps方法,以便在获取数据时通知子级list。在这种方法中,你可以设置新的状态:
componentWillReceiveProps: function(newProps) {
this.setState({data: this.props.data});
}
完成此操作后,react将为您重新渲染列表。
另一个更新:为了说明这是如何工作的,我在这里举了一个例子。
下面是这个的JS代码:
let todos = ["Run","Swim","Skate"];
class MyList extends React.Component{
componentWillMount() {
console.log("Props are: ", this.props);
this.setState({list: this.props.items});
}
componentWillReceiveProps(newProps) {
console.log("Received Props are: ", newProps);
this.setState({list: newProps.items});
}
render() {
return (<ul>
{this.state.list.map((todo) => <li>{todo}</li>)}
</ul>);
}
}
class App extends React.Component{
constructor() {
super();
console.log("State is: ", this.state);
}
componentWillMount() {
this.setState({items: ["Fly"]});
}
componentDidMount() {
setTimeout(function(){
console.log("After 2 secs");
this.setState({items: todos});
}.bind(this), 2000);
}
render() {
return (<MyList items={this.state.items}/>);
}
}
ReactDOM.render(<App/>, document.getElementById("app"));
- 跨源请求阻止Spring REST服务+AJAX
- Ajax不调用Web服务
- Ajax发布到双节点NLB上的web服务
- 将Ajax数据发布到PHP REST服务
- 可以't使用ajax调用将值传递给Web服务
- 使用Jquery ajax将数据发送到服务
- ajax 可以使用绝对 url 来调用 Web 服务吗?
- 使用Ajax使用REST服务-同源策略
- ajax调用wcf服务返回错误
- AJAX加载JSON数据并将其存储在angularjs服务中
- 使用ajax将数据发布到asmx web服务并使用javascript函数在html页面中编写响应时出错
- 在哪里操作通过 AJAX 服务获得的数据?链接 fn 或控制器
- jQuery.ajax 从 wcf 服务和显示中获取图像
- AJAX 可访问的长时间运行的服务任务阻止在启用 ASP.NET 兼容性/会话的环境中的后续 AJAX 服务请求
- ajax 服务 php 文件的安全性
- 编写懒惰ajax服务的最佳实践
- 在跨域jquery/Ajax服务调用中遇到麻烦
- 访问通过Ajax服务的HTML片段中返回的JSON
- 我如何从这个angular ajax服务中访问$q (promise service) ?
- 在React.js中的组件之间传递Ajax/服务数据