[英]How to pre-fill a form with data from a GraphQL query using Apollo 2?
我很難將Apollo 2 GraphQL查詢中的數據轉換為常規表單字段。
其他人如何接近這個? 以前嘗試過Relay並成功使用組件構造函數設置表單字段狀態。
然而,在阿波羅,即使在搜索了幾個小時並閱讀了大量的文檔之后,我仍然處於黑暗中......
在組件初始化期間,狀態始終返回null,因為在稍后階段設置了props。 我試着在加載后設置它,但這讓我陷入了無盡的循環......
我完全迷失了:/
這就是我現在想出來的......它有效。 但這是否是推薦的方法來滿足這一要求?
import React from 'react';
import { Route, Redirect, Switch } from "react-router-dom";
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
// SEMANTIC-UI REACT
import { Container, Form, Button, Loader, Message } from "semantic-ui-react";
const MY_QUERY = gql`
query {
erp(id:"RXJwTm9kZToy") {
id
name
code
}
}`;
class Test extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
componentWillReceiveProps(newProps) {
if (newProps !== this.props) {
this.setState({
erp_name: (newProps.data.erp || "").name,
erp_code: (newProps.data.erp || "").code
});
}
}
render() {
if (this.props.data.loading) {
return <Loader active inline='centered' />;
} else if (this.props.data.error) {
return <Message error content={this.props.data.error.message} />;
} else {
return (
<Form>
<ul>
<li key={this.props.data.erp.id}>{this.props.data.erp.name}</li>
</ul>
<Form.Input name="erp_name" label="ERP Name" placeholder="Name" value={this.state.erp_name} />
<Form.Input name="erp_code" label="ERP Code" placeholder="Code" value={this.state.erp_code} />
<Button type='submit'>Submit</Button>
</Form>
);
}
}
}
export default graphql(MY_QUERY)(Test);
這是React和ReduxForm的一個小例子。 也許這會對你有所幫助。
在此示例中,查詢將在組件初始化時執行,並將返回填寫表單所需的數據。
我希望它對你有所幫助!
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { compose } from 'recompose'
import { graphql, withApollo, gql } from 'react-apollo'
import { Form } from 'redux-form'
class MyExampleComponent extends Component {
render() {
const { userData } = this.props
return (
<Form
initialValues={userData}
/>
)
}
}
MyExampleComponent.propTypes = {
userData: PropTypes.object
}
const query = gql`
query getUser($userId: ID) {
user(id: $userId) {
age
firstName
lastName
}
}
`
export default compose(
withApollo,
graphql(query, {
props: ({ data }) => ({
isLoading: data.loading,
userData: data.user
}),
options: ({ params }) => ({
variables: { id: params.id }
})
})
)(MyExampleComponent)
我目前使用的方法是即使數據尚不可用也始終呈現表單。 這樣,裝載道具就不需要檢查,因為它假定所有數據都可用。 如果您確實檢查了加載道具並且只在加載數據時呈現表單,那么客戶端瀏覽器會等待顯示表單直到數據可用,這可能會讓人感到煩惱,尤其是當數據可用時間更長時。 最好讓瀏覽器利用這個空閑時間在DOM中構建表單。
但是如何從graphql查詢和prefill中了解初始狀態?
狀態用於保持表單輸入數據,而來自graphql源的初始數據永遠不會加載到狀態! 每次需要(真值)數據時,都會重新計算。 這個重新計算應該只在一個地方進行,所以我引入了一個輔助函數getTruthData()。 無論你需要真值數據,你都可以通過這個輔助函數來處理它。 例如,渲染以及將更新的數據提交回graphql mutate。 並且只有在此getTruthData()函數中才需要根據可用性返回數據。 不要介意性能,因為重新計算真實數據真的很快,緩存只會因React重新渲染的性質而引入不可預測的結果。
我(試圖)更新你的代碼。 我做了什么:
編碼:
class Test extends React.Component {
constructor(props) {
super(props);
this.getProfileTruth = this.getProfileTruth.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
getTruthData() {
return {
erp_id: this.props.data.erp.id || '',
erp_name: this.state.erp_name || this.props.data.erp.name || '',
erp_code: this.state.erp_code || this.props.data.erp.code || '',
};
// OR you might want to use the underscore helper for larger forms with more fields to keep like this:
return _.defaults(
{},
this.state,
this.props.data.erp,
{ erp_name: '', erp_code: '' },
);
}
handleChange(data) {
this.setState(data);
}
handleSubmit(e) {
e.preventDefault();
const { erp_id, erp_name, erp_code } = this.getProfileTruth();
// run a mutate on graphql
}
render() {
const { erp_id, erp_name, erp_code } = this.getProfileTruth();
return (
<Form>
<ul>
<li key={erp_id}>{erp.name}</li>
</ul>
<Form.Input
name="erp_name"
label="ERP Name"
placeholder="Name"
value={erp_name}
onChange={e => this.handleChange({ erp_name: e.target.value })} />
<Form.Input
name="erp_code"
label="ERP Code"
placeholder="Code"
value={erp_code}
onChange={e => this.handleChange({ erp_code: e.target.value })} />
<Button type='submit' onClick={this.handleSubmit}>Submit</Button>
</Form>
);
}
}
副作用可能是如果來自graphql的數據需要很長時間才能輸入表單。 使用受控表單,您可以檢查handleChange以僅在正確加載數據時允許更改。 你甚至可以取消激活按鈕的樣式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.