我试图将setState()设置为我从graphQL获得的查询结果,但是我很难找到如何执行此操作,因为它将始终加载,或者它仅用于props。我首先设置状态
constructor (props) {
super(props);
this.state = { data: [] };
然后我有这个查询
const AllParams = gql`
query AllParamsQuery {
params {
id,
param,
input
}
}`
当它回来时我可以用this.props.AllParamsQuery.params
访问它
怎么以及何时我应该this.setState({ data: this.props.AllParamsQuery.params })
没有它返回{data: undefined}
?
我没有找到一种方法让它等待,而它是undefined
AKA loading: true
然后setState
。我试过componentDidMount()
和componentWillReceiveProps()
包括async function(){...await...}
但是不成功,我可能做错了。任何人都知道如何正确地做这个或有一个例子?
编辑+答案:你不应该设置状态,只需将它留在道具中。看看这个链接:“为什么设置道具作为react.js中的状态是亵渎”http://johnnyji.me/react/2015/06/26/why-setting-props-as-state-in-react-is-blasphemy.html更新道具还有更多问题,但是在这个应用程序创建教程中可以找到一些很好的例子:https://www.howtographql.com/react-apollo/8-subscriptions/
一个简单的解决方案是分离您的Apollo查询组件和React状态组件。来自Redux,使用mapStateToProps
和componentWillReceiveProps
转换为本地组件状态的传入道具并不罕见。然而,这种模式与阿波罗的<Query />
混乱。
因此,只需创建一个单独的组件来获取数据:
...
export class WidgetsContainer extends Component {
render (
<Query query={GET_WIDGETS}>
{({ loading, error, data }) => {
if (loading) return <Loader active inline="centered" />;
const { widgets } = data;
return (
<Widgets widgets={widgets} />
)
}}
</Query>
)
}
现在Widgets
组件现在可以正常使用setState
:
...
export class Widgets extends Component {
...
constructor(props) {
super()
const { widgets } = props;
this.state = {
filteredWidgets: widgets
};
}
filterWidget = e => {
// some filtering logic
this.setState({ filteredWidgets });
}
render() {
const { filteredWidgets } = this.state;
return (
<div>
<input type="text" onChange={this.filterWidgets} />
{filteredWidgets.count}
</div>
)
}
}
将其设置为州的原因是什么?请记住,Apollo Client使用内部redux存储来管理查询。如果您尝试根据查询中的某些更改触发重新渲染,则应使用refetchQueries()。如果你绝对需要将它存储在本地状态,我会假设您可以比较componentWillReceiveProps中的nextProps以检测何时加载(从apollo客户端执行查询时返回的值)已更改,然后更新您的状态。
我有一个类似的问题(虽然它发生的原因完全不同)。我的状态一直未定义。我能用React中间件解决它。它可以很容易地避免这个问题。我最终使用了superagent。