前言
上节课我们讲到如何使用Apollo
获取到数据库的Person
列表,这节课,我们将会继续使用它新增Person
、Job
数据
AddPerson.js
首先,我们在components
文件夹下创建AddPerson.js
,代码内容如下所示:
import { gql, useQuery } from '@apollo/client'
const JOBS_LIST = gql`
{
jobs {
name
id
}
}
`
function GetJobsList() {
const { loading, error, data } = useQuery(JOBS_LIST)
if (loading) return <option>Loading...</option>
if (error) return <option>Error: {error}</option>
return data.jobs.map(({name, id}) => {
return <option key={id} value={id}>{name}</option>
})
}
const AddPerson = props => {
return (
<form id="addPerson">
<div className='field'>
<label>姓名:</label>
<input type="text"/>
</div>
<div className='field'>
<label>性别:</label>
<select>
<option>选择性别</option>
<option value="male">男</option>
<option value="female">女</option>
</select>
</div>
<div className='field'>
<label>年龄:</label>
<input type="number"/>
</div>
<div className='field'>
<label>职位:</label>
<select>
<option>选择职位</option>
{GetJobsList()}
</select>
</div>
<button>+</button>
</form>
)
}
export default AddPerson;
GetJobsList
这个方法里返回的option
里面的value
值必须是jobId
,它可以将Person
和Job
关联起来。忘记的同学可以看看我之前的文章
在这里我们创建了form
表单,目前点击+
按钮不会有任何反应,这个功能会在mutation
里添加
App.js
在App.js
里增加AddPerson.js
的引入,部分代码如下所示:
import AddPerson from './components/AddPerson';
function App() {
return (
<ApolloProvider client={client}>
<div id="main">
...
<AddPerson></AddPerson>
</div>
</ApolloProvider>
);
}
刷新页面,可看到如下效果
queries
在src
目录下创建queries
文件夹,在该文件夹下创建queries.js
,我们将前面的gql
查询代码全部移至该js
文件内,代码如下所示:
import { gql } from '@apollo/client'
const JOBS_LIST = gql`
{
jobs {
name
id
}
}
`
const PERSON_LIST = gql`
{
persons {
name
}
}
`
export {
JOBS_LIST,
PERSON_LIST
}
对AddPerson.js
、PersonList.js
做相应的引入更改
初始化响应式数据
react
提供了useState
方法,可使数据变成响应式(即数据一旦更改,视图可检测到并发生变化)
在AddPerson.js
里添加如下功能,代码如下所示:
import { useState } from 'react'
import { useQuery } from '@apollo/client'
import { JOBS_LIST } from '../queries/queries'
function GetJobsList() {
const { loading, error, data } = useQuery(JOBS_LIST)
if (loading) return <option>Loading...</option>
if (error) return <option>Error: {error}</option>
return data.jobs.map(({name, id}) => {
return <option key={id} value={id}>{name}</option>
})
}
const AddPerson = props => {
const [name, setName] = useState('')
const [sex, setSex] = useState('')
const [jobId, setJobId] = useState('')
const [age, setAge] = useState(0)
function submitForm(e) {
e.preventDefault()
console.log(name)
console.log(sex)
console.log(age)
console.log(jobId)
}
return (
<form id="addPerson" onSubmit={submitForm}>
<div className='field'>
<label>姓名:</label>
<input type="text" onChange={e => setName(e.target.value)}/>
</div>
<div className='field'>
<label>性别:</label>
<select onChange={e => setSex(e.target.value)}>
<option>选择性别</option>
<option value="male">男</option>
<option value="female">女</option>
</select>
</div>
<div className='field'>
<label>年龄:</label>
<input type="number" onChange={e => setAge(e.target.value)}/>
</div>
<div className='field'>
<label>职位:</label>
<select onChange={e => setJobId(e.target.value)}>
<option>选择职位</option>
{GetJobsList()}
</select>
</div>
<button>+</button>
</form>
)
}
export default AddPerson;
在submitForm
方法内添加e.preventDefault()
,这是js
功能,目的是阻止页面自动刷新
在浏览器端,输入各个值,控制台可显示对应的值,如下图所示:
增加mutation
在queries.js
里增加ADD_PERSON_MUTATION
代码,如下所示:
const ADD_PERSON_MUTATION = gql`
mutation($name:String!,$age:Int!,$sex:String!,$jobId: ID!){
addPerson(name:$name, age: $age, sex: $sex, jobId: $jobId) {
name
id
}
}
`
export {
JOBS_LIST,
PERSON_LIST,
ADD_PERSON_MUTATION
}
注意:这里的
age
类型为Int
,感叹号表示该参数为必传参数
AddPerson.js
新增的代码如下所示:
import { useQuery, useMutation } from '@apollo/client'
import { JOBS_LIST, ADD_PERSON_MUTATION } from '../queries/queries'
const AddPerson = props => {
const [name, setName] = useState('')
const [sex, setSex] = useState('')
const [jobId, setJobId] = useState('')
const [age, setAge] = useState(0)
const [addPerson, { data, loading, error }] = useMutation(ADD_PERSON_MUTATION)
function submitForm(e) {
e.preventDefault()
try {
addPerson({
variables: {
name,
sex,
jobId,
age: Number(age)
}
})
if (error) console.error(`Service Error: ${error}`)
resetForm()
} catch (err) {
console.error(err)
}
}
function resetForm() {
setName('')
setSex('')
setAge(0)
setJobId('')
}
return (
<form id="addPerson" onSubmit={e => submitForm(e)}>
...
</form>
)
}
在浏览器表单上输入信息,点击+
按钮,已成功添加,如下图所示:
刷新界面,lucy
已显示在界面上
新增数据后,界面实时响应显示
如何做到数据新增成功后,界面实时显示新增的数据呢?
需在AddPerson.js
里新增如下代码:
import { JOBS_LIST, PERSON_LIST, ADD_PERSON_MUTATION } from '../queries/queries'
...
function submitForm(e) {
e.preventDefault()
try {
addPerson({
variables: {
...
},
refetchQueries: [{query: PERSON_LIST}]
})
...
} catch (err) {
console.error(err)
}
}
界面效果如下所示: