[英]How to update component when state changes
Heyia,這里的React noob,對於可能愚蠢的問題感到抱歉,我是幾天前才剛開始的,無法真正解決這個問題。
我正在創建一個包含從Twitter API獲取的數據的對象數組,並將其發送回我想進一步使用它的App組件。
我得到了數組,將其設置為App組件的狀態,但是無法實現更改立即顯示在頁面上–我的意思是在從用戶輸入獲得用戶名並由返回數組的函數處理后立即打印列表。
這可能很簡單,但我還沒有完全掌握組件之間的通信及其生命周期的想法(如果相關,我不確定),所以我無法弄清楚。
有人可以幫幫我嗎?
這是我的代碼
App.js文件
class App extends Component {
constructor(props) {
super(props);
this.state = {
username: "",
tweets: [] // here I need to get the array of objects
};
this.submitHandler = this.submitHandler.bind(this);
}
// following methods are used to first get a username by user input
submitHandler = (event) => {
event.preventDefault();
this.useUsername();
};
usernameChangeHandler = (event) => {
this.setState({username: event.target.value});
};
// this one's calling the function for obtaining the tweets, code below
useUsername = () => {
this.setState({tweets: fetchTweets(this.state.username)});
};
render() {
return (
<div className="App">
<Grid fluid>
<Row>
<form>
<label>
Username:
<input type="text" value={this.state.username} onChange={this.usernameChangeHandler}/>
</label>
<button type="submit" onClick={this.submitHandler.bind(this)}>Submit</button>
</form>
</Row>
<Row>
<div className="jumbotron text-center">
// this should be updated when state changes
<Table list={this.state.tweets}/>
</div>
</Row>
</Grid>
</div>
);
}
}
const Table = ({list}) => {
return (
<div>
{
list.map((item) =>
<div key={item.id}>
<h3>{item.text}</h3>
<h4>by {item.author}</h4>
<h5>by {item.date}</h5>
<p>{item.num_of_likes} Likes; Mentions: {item.mentions}; Hashtags: {item.hashtags}</p>
</div>
)
}
</div>
)
};
函數處理用戶輸入並返回數組
export const fetchTweets = username => {
let alltweets = [];
twitter.get('statuses/user_timeline', {screen_name: username, count: 50}, function (error, tweets, response) {
if (!error) {
for (let i = 0; i < 50; i++) {
let tw = tweets[i];
let newtweet = new Tweet(i, tw.text, tw.user.screen_name, tw.created_at,
tw.favorite_count, tw.entities.user_mentions, tw.entities.hashtags);
alltweets.push(newtweet);
}
} else {
console.log("Error occurred while retrieving tweets: " + error);
return error;
}
});
return alltweets;
};
這是我根據Twitter數據創建的對象類別
export class Tweet {
constructor(id, text, author, date, num_of_likes, mentions, hashtags) {
this.id = id;
this.text = text;
this.author = author;
this.date = date;
this.num_of_likes = num_of_likes;
this.mentions = mentions;
this.hashtags = hashtags;
}
}
任何幫助,高度贊賞。
fetchTweets函數現在無法正常工作的原因是因為twitter.get
函數是異步的 ,這意味着回調函數在調用后不會立即發生。 稍后會發生。 調用時會發生以下情況:
alltweets
數組,並將其設置為[]
twitter.get
被稱為 alltweets
數組返回到react組件 twitter.get
完成,得到結果,並向數組添加內容 這里缺少的部分是setState
需要在 twitter.get
完成之后而不是之前完成。 實現此目的最直接的方法是允許fetchTweets
函數接受另一個函數,該函數在twitter.get
完成時被調用。 這樣做的方法如下:
// new fetchTweets
export const fetchTweets = (username, handleResult) => {
twitter.get("statuses/user_timeline", { screen_name: username, count: 50 }, function(error, tweets, response) {
if (!error) {
let alltweets = []
for (let i = 0; i < 50; i++) {
let tw = tweets[i]
let newtweet = new Tweet(i, tw.text, tw.user.screen_name, tw.created_at, tw.favorite_count, tw.entities.user_mentions, tw.entities.hashtags)
alltweets.push(newtweet)
}
// callback function is called here
handleResult(alltweets)
} else {
console.log("Error occurred while retrieving tweets: " + error)
}
})
}
// in your react component
useUsername = () => {
fetchTweets(this.state.username, alltweets => {
this.setState({ tweets: alltweets })
})
}
做法不好。
使函數fetchTweets
返回以數據解析的承諾或以錯誤拒絕的承諾。
export const fetchTweets = username => {
let alltweets = [];
return new Promise((resolve, reject) => {
twitter
.get('statuses/user_timeline', {
screen_name: username,
count: 50
}, function (error, tweets, response) {
if (!error) {
///construct alltweets
resolve(alltweets);
} else {
reject(error);
}
});
});
};
而不是從submitHandler
調用this.useUsername()
, submitHandler
調用fetchTweets
並在其中設置setState
。
submitHandler = (event) => {
event.preventDefault();
fetchTweets().then((alltweets) => {
this.setState({tweets: alltweets})
}).catch((error) => console.log(error));
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.