React-router(path = "profile /:username")によって読み込まれたProfileコンポーネントがあり、コンポーネント自体は次のようになります。
...
import { fetchUser } from '../actions/user';
class Profile extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const { username } = this.props;
this.fetchUser(username);
}
componentWillReceiveProps(nextProps) {
const { username } = nextProps.params;
this.fetchUser(username);
}
fetchUser(username) {
const { dispatch } = this.props;
dispatch(fetchUser(username));
}
render() {...}
}
export default connect((state, ownProps) => {
return {
username: ownProps.params.username,
isAuthenticated: state.auth.isAuthenticated
};
})(Profile);
そして、fetchUserアクションは次のようになります(redux-api-middleware):
function fetchUser(id) {
let token = localStorage.getItem('jwt');
return {
[CALL_API]: {
endpoint: `http://localhost:3000/api/users/${id}`,
method: 'GET',
headers: { 'x-access-token': token },
types: [FETCH_USER_REQUEST, FETCH_USER_SUCCESS, FETCH_USER_FAILURE]
}
}
}
ComponentWillReceiveProps関数を追加した理由は、URLが別の:usernameに変更されたときに反応し、そのユーザーのプロファイル情報をロードするためです。一見、すべてが機能しているように見えますが、デバッグ中に、componentWillReceiveProps関数が無限ループで呼び出されていることがわかりました。理由はわかりません。 componentWillReceivePropsを削除すると、プロファイルは新しいユーザー名で更新されませんが、ループの問題は発生しません。何か案は?
componentWillReceiveProps
を呼び出すと、Propsを更新するアクションが送出されるため、fetchUser
は無限ループに入っています。
アクションをディスパッチする前に、比較を追加して、特定の小道具が変更されたかどうかを確認します。 編集:
React 16.3 +でcomponentWillReceiveProps
はゆっくりになります非推奨 。
componentDidUpdate
の代わりにcomponentWillReceiveProps
を使用することは推奨です
componentDidUpdate(prevProps) {
if (this.props.params.username !== prevProps.params.username) {
dispatch(fetchUser(username));
}
}
小道具を比較する条件を追加してみてください。コンポーネントで必要な場合。
componentWillRecieveProps(nextProps){
if(nextProps.value !== this.props.value)
dispatch(action()) //do dispatch here
}
Profile /:usernameのようないくつかのパスパラメータを使用してルートを反応させる場合、単純にprops.location.pathnameを比較できます。
componentWillReceiveProps(nextProps){
if(nextProps.location.pathname !== this.props.location.pathname){
dispatch()
}
}