Reactjs 如果selectedItem redux状态将被其他组件使用,那么我将选择选项2,否则选择选项4。我目前也有类似的问题,您最终使用了哪个选项?我目前正在使用选项2。但是选项2会一直有效吗?我的印象是componentWillReceiveProps仅在道具
Reactjs 如果selectedItem redux状态将被其他组件使用,那么我将选择选项2,否则选择选项4。我目前也有类似的问题,您最终使用了哪个选项?我目前正在使用选项2。但是选项2会一直有效吗?我的印象是componentWillReceiveProps仅在道具,reactjs,apollostack,react-apollo,apollo-client,Reactjs,Apollostack,React Apollo,Apollo Client,如果selectedItem redux状态将被其他组件使用,那么我将选择选项2,否则选择选项4。我目前也有类似的问题,您最终使用了哪个选项?我目前正在使用选项2。但是选项2会一直有效吗?我的印象是componentWillReceiveProps仅在道具更改时运行,而不一定在第一次渲染时运行。因此,如果您的道具没有发生变化,这个生命周期方法将不会运行,您的操作也不会被调度。不过,也许我误解了该生命周期方法的语义。@AdamDonahue React文档清楚地指出:注意,即使道具没有更改,Rea
如果selectedItem redux状态将被其他组件使用,那么我将选择选项2,否则选择选项4。我目前也有类似的问题,您最终使用了哪个选项?我目前正在使用选项2。但是选项2会一直有效吗?我的印象是componentWillReceiveProps仅在道具更改时运行,而不一定在第一次渲染时运行。因此,如果您的道具没有发生变化,这个生命周期方法将不会运行,您的操作也不会被调度。不过,也许我误解了该生命周期方法的语义。@AdamDonahue React文档清楚地指出:注意,即使道具没有更改,React也可能调用此方法,因此,如果您只想处理更改,请确保比较当前值和下一个值。当父组件导致组件重新渲染时,可能会发生这种情况@我想你误解了。我的意思是,如果您的初始道具集从未更改,那么componentWillReceiveProps可能无法运行。至少,这是我对该生命周期方法文档的以下部分的解释:“React不会在装载期间使用初始道具调用componentWillReceiveProps。它只会在某些组件道具可能更新时调用此方法。”显然,上面的选项2是不完整的。或者可以,除非你以某种方式强制改变道具。
const fetchList = graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => {
return {
loading,
list: dataList,
};
}
}
);
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);
}
}
})
);
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)
const enhance = compose(
connect(
function mapStateToProps(state) {
return {
selectedItem: getSelectedItem(state),
};
}, {
selectItem, // action creator
}
),
graphql(
dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => {
if (!loading && dataList && dataList.length) {
selectItem(dataList[dataList.length - 1].id);
}
return {
loading,
items: dataList,
}
},
}
),
);
componentDidUpdate(prevProps, prevState) {
if (this.props.data !== prevProps.data) {
dispatch some action that set whatever you need to set
}
}
const enhance = compose(
connect(),
graphql(dataListQuery, {
options: ({ listId }) => ({
variables: {
listId,
},
}),
props: ({ data: { loading, dataList } }) => ({
isLoading:loading,
isData:!!dataList,
dataList
}),
}
),
withLoader
)(Component)
function withLoader(WrappedComponent) {
class comp extends React.PureComponent {
render(){
return this.props.isData?<WrappedComponent {...this.props}/>:<Loading/>
}
}
}
export default compose(
connect(
state => ({ /* ... */ }),
dispatch => ({
someReduxAction: (payload) => dispatch({ /* ... */ }),
anotherReduxAction: (payload) => dispatch({ /* ... */ }),
}),
),
graphqlWithDone(someQuery, {
name: 'someQuery',
options: props => ({ /* ... */ }),
props: props => ({ /* ... */ }),
makeDone: props => dataFromQuery => props.someReduxAction(dataFromQuery)
}),
graphqlWithDone(anotherQuery, {
name: 'anotherQuery',
options: props => ({ /* ... */ }),
props: props => ({ /* ... */ }),
makeDone: props => dataFromQuery => props.anotherReduxAction(dataFromQuery)
})
)(SomeComponent)
const graphqlWithDone = (query, queryConfig) => (Wrapped) => {
const enhance = graphql(query, {
...queryConfig,
props: (props) => ({
queryData: { ...( props[queryConfig.name] || props.data ) },
queryProps: queryConfig.props(props),
})
})
class GraphQLWithDone extends Component {
state = {
isDataHandled: false
}
get wrappedProps () {
const resultProps = { ...this.props };
delete resultProps.queryData;
delete resultProps.queryProps;
return { ...resultProps, ...this.props.queryProps }
}
get shouldHandleLoadedData () {
return (
!this.props.queryData.error &&
!this.props.queryData.loading &&
!this.state.isDataHandled
)
}
componentDidUpdate() {
this.shouldHandleLoadedData &&
this.handleLoadedData(this.props.queryData);
}
handleLoadedData = (data) => {
if (!makeDone || !isFunction(makeDone)) return;
const done = makeDone(this.wrappedProps)
this.setState({ isDataHandled: true }, () => { done(data) })
}
render() {
return <Wrapped {...this.wrappedProps} />
}
}
return enhance(GraphQLWithDone)
}