Javascript 在React.js中的组件之间传递Ajax/服务数据
我试图传递React应用程序的一个组件中接收到的数据。成功后,我将获取接收到的数据并设置状态,然后尝试将该数据作为下一个组件的属性传递。进入第二个组件后,我需要通过Javascript 在React.js中的组件之间传递Ajax/服务数据,javascript,ajax,reactjs,Javascript,Ajax,Reactjs,我试图传递React应用程序的一个组件中接收到的数据。成功后,我将获取接收到的数据并设置状态,然后尝试将该数据作为下一个组件的属性传递。进入第二个组件后,我需要通过this.state访问传递的数据,以便稍后更改该组件中的状态。在从服务接收数据之前,我似乎遇到了DOM呈现的问题。我尝试在中传递一个已经加载的值数组来代替中的this.state.data,它似乎执行得很好。如何确保在呈现DOM之前已从服务接收到数据,以便将数据一直传递到每个组件 编辑:添加了List元素的完整实现,因此解释this
this.state
访问传递的数据,以便稍后更改该组件中的状态。在从服务接收数据之前,我似乎遇到了DOM呈现的问题。我尝试在
中传递一个已经加载的值数组来代替中的this.state.data
,它似乎执行得很好。如何确保在呈现DOM之前已从服务接收到数据,以便将数据一直传递到每个组件
编辑:添加了List元素的完整实现,因此解释this.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')
);
var-Box=React.createClass({
getInitialState:函数(){
返回{data:[]};
},
loadTodosFromServer:函数(){
$.ajax({
url:this.props.url,
数据类型:“json”,
键入:“GET”,
cache:false,
成功:功能(数据响应){
this.setState({data:dataResponse});
}.绑定(此),
错误:函数(xhr、状态、错误){
console.error(this.props.url,status,err.toString());
}.绑定(此)
});
},
componentDidMount:function(){
这是loadFromServer();
},
render:function(){
返回();
}
});
var List=React.createClass({
getInitialState:函数(){
返回{data:this.props.data};
},
dragStart:函数(e){
this.drad=e.currentTarget;
e、 dataTransfer.effectAllowed='move';
//Firefox需要设置数据传输数据
e、 setData(“text/html”,例如currentTarget);
},
绘图:功能(e){
this.dradded.style.display=“block”;
this.dragged.parentNode.removeChild(占位符);
//更新数据
var data=this.state.data;
var from=Number(this.draugd.dataset.id);
var to=Number(this.over.dataset.id);
如果(从<到)到--;
如果(this.nodePlacement==“after”)到++;
数据拼接(到,0,数据拼接(从,1)[0]);
this.setState({data:data});
},
德拉戈弗:功能(e){
e、 预防默认值();
this.dradded.style.display=“无”;
if(e.target.className==“占位符”)返回;
这个。超过=e。目标;
//在dragOver方法内部
var Relay=e.clientY—this.over.offsetTop;
var height=this.over.offsetHeight/2;
var parent=e.target.parentNode;
如果(依赖>高度){
this.nodePlacement=“after”;
parent.insertBefore(占位符,例如target.nextElementSibling);
}
否则如果(依赖<高度){
this.nodePlacement=“before”
parent.insertBefore(占位符,例如target);
}
},
render:function(){
var结果=this.state.data;
返回(
{
结果.映射(函数(结果,i){
返回(
- {result}
)
})
}
);
}
});
ReactDOM.render(
,document.getElementById('content'))
);
组件加载后的数据加载未呈现数据的原因是列表中的这一行。呈现函数:
var results = this.state.data;
实际上,您已经复制了原始道具,并使用getInitialState方法将它们分配给列表组件中的状态。然后你的状态和道具就脱钩了。这意味着,如果列表组件上的props.data发生更改,则状态不知道它,因此不会重新呈现任何内容
因此,与其使用state初始化results变量,不如使用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>
);
}
});
执行此操作后,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"));
let todos=[“跑”、“游”、“滑”];
类MyList扩展了React.Component{
组件willmount(){
log(“Props是:”,this.Props);
this.setState({list:this.props.items});
}
组件将接收道具(新道具){
log(“收到的道具是:”,newProps);
this.setState({list:newProps.items});
}
render(){
返回(
{this.state.list.map((todo)=>- {todo}
)}
);
}
}
类应用程序扩展了React.Component{
构造函数(){
超级();
log(“状态为:”,this.State);
}
组件willmount(){
this.setState({items:[“Fly”]});
}
componentDidMount(){
setTimeout(函数(){
控制台日志(“2秒后”);
this.setState({items:todos});
}.bind(this),2000年);
}
render(){
返回();
}
}
ReactDOM.render(,document.getElementById(“app”);
是否要更改列表组件内的状态?@kumarm是的,这是我选择使用this.state.data时的意图。我将此值从props更改为state,以便在加载初始列表后更新状态。我的目的是创建一个项目列表,然后能够在通过拖放界面生成初始列表后对其重新排序。我仍然可以使用this.props方法来实现这种类型的功能吗?为了便于阅读,我省略了这一部分。谢谢@NightMarcher。我已经相应地更新了我的答案。@NightMarcher这解决了你的问题吗?如果是,请将此标记为答案。谢谢,谢谢!!直到现在我才有机会尝试一下。这正是我想要的。
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"));