react apollo が提供する HOCを使用してデータのリストを取得していますgraphql
。例:
const fetchList = graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => {
return {
loading,
list: dataList,
};
}
}
);
制御されたラジオ ボタン グループにリストを表示しており、デフォルトで項目の 1 つを選択する必要があります。id
選択された項目の は Redux ストアに保存されます。
そこで質問ですが、selectedItem
クエリが正常に返された後に Redux ストアを更新する (つまり、 を設定する) にはどうすればよいのでしょうか?
頭に浮かんだいくつかの選択肢:
オプション1
Redux リデューサーでアクションをリッスンする必要がありますかAPOLLO_QUERY_RESULT
? しかし、それはちょっと厄介です。なぜなら、クエリがすでに実行されているかどうかの両方をリッスンする必要があるからです。また、APOLLO_QUERY_RESULT
プロパティはアクションにのみ存在し、アクションには存在しません。そのため、すべてのアクションを分析して、それがどこから来たのかを知る必要があります。クエリ結果のアクションを識別する簡単で直接的な方法はないでしょうか?APOLLO_QUERY_RESULT_CLIENT
operationName
APOLLO_QUERY_RESULT
APOLLO_QUERY_RESULT_CLIENT
APOLLO_QUERY_RESULT_CLIENT
オプション2
SELECT_LIST_ITEM
例えば、componentWillReceiveProps
(再構成する):
const enhance = compose(
connect(
function mapStateToProps(state) {
return {
selectedItem: getSelectedItem(state),
};
}, {
selectItem, // action creator
}
),
graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => ({
loading,
items: dataList,
}),
}
),
lifecycle({
componentWillReceiveProps(nextProps) {
const {
loading,
items,
selectedItem,
selectItem,
} = nextProps;
if (!selectedItem && !loading && items && items.length) {
selectItem(items[items.length - 1].id);
}
}
})
);
オプション3
を注入して Apollo クライアントを直接使用しwithApollo
、 でアクションをディスパッチする必要がありますかclient.query(...).then(result => { /* some logic */ selectItem(...)})
。ただし、そうすると react-apollo 統合の利点がすべて失われるため、実際には選択肢ではありません。
オプション4
クエリが返された後、Redux ストアをまったく更新しないほうがよいでしょうか。設定されている場合は を返し、設定されていない場合はストアの一部selectedItem
を参照して導出を試みるセレクターを実装することもできるためです。apollo
選択肢のどれも満足できません。では、どうすれば正しく実行できるのでしょうか?
ベストアンサー1
私は似たようなことをするだろうオプション2ただし、ライフサイクル メソッドは実際のコンポーネント内に配置されます。これにより、ライフサイクル内のビジネス ロジックは、Container から継承されたプロパティから分離されます。
つまり、次のようになります。
class yourComponent extends Component{
componentWillReceiveProps(nextProps) {
const {
loading,
items,
selectedItem,
selectItem,
} = nextProps;
if (!selectedItem && !loading && items && items.length) {
selectItem(items[items.length - 1].id);
}
}
render(){...}
}
// Connect redux and graphQL to the Component
const yourComponentWithGraphQL = graphql(...)(yourComponent);
export default connect(mapStateToProps, mapDispatchToProps)(yourComponentWithGraphQL)