如何使用RTK查询设置请求主体以更新记录?

huangapple go评论79阅读模式
英文:

How to set body in request to update record using RTK query?

问题

EditEmployee组件中,在编辑后,当我点击"保存更改"按钮时,updateEmployee方法出现了某种原因不能发送PUT请求的请求体。

我在这里做错了什么?

EditEmployee.js

import React, { useState } from 'react';

import { useUpdateEmployeeMutation } from "./employeesApiSlice";

function EditEmployee(props) {
    const [updateEmployee] = useUpdateEmployeeMutation();
    
    const [updatedFirstName, setUpdatedFirstName] = useState(props.employee.firstName);
    const [updatedLastName, setUpdatedLastName] = useState(props.employee.lastName);
    const [updatedPosition, setUpdatedPosition] = useState(props.employee.position);

    const jobPositions = ['Labor', 'Worker', 'Supervisor', 'Manager', 'HR', 'Director', 'CEO']
        .map((jobPosition, i) => (
            <Col key={i}>
                <Form.Group className="mb-3" controlId={jobPosition.toLowerCase()}>
                    <Form.Check
                        type="radio"
                        name="position"
                        label={jobPosition}
                        value={jobPosition.toLowerCase()}
                        defaultChecked={props.employee.position.toLowerCase() === jobPosition.toLowerCase()}
                        onChange={e => setUpdatedPosition(e.target.value)}
                    />
                </Form.Group>
            </Col>
    ));

    function handleSaveChanges() {
        const employee = {
            firstName: updatedFirstName,
            lastName: updatedLastName,
            position: updatedPosition
        }
        updateEmployee(props.employee.id, employee)
    }

    return (
        <>
           <Form>
              <Form.Group className="mb-3" controlId="formFirstName">
                 <Form.Label>First Name</Form.Label>
                 <Form.Control type="text" defaultValue={updatedFirstName} onChange={e => setUpdatedFirstName(e.target.value)} />
              </Form.Group>
              <Form.Group className="mb-3" controlId="formLastName">
                 <Form.Label>Last Name</Form.Label>
                 <Form.Control type="text" defaultValue={updatedLastName} onChange={e => setUpdatedLastName(e.target.value)} />
              </Form.Group>
              <Container>
                 <Row>
                    {jobPositions}
                 </Row>
              </Container>
           </Form>
                
           <Button variant="success" onClick={() => handleSaveChanges()}>
               Save Changes
           </Button>
       </>
    );
}

export default EditEmployee;

employeeApiSlice.js

import { apiSlice } from "../../app/api/apiSlice";

export const employeesApiSlice = apiSlice.injectEndpoints({
    tagTypes: ['Employees'],
    endpoints: (builder) => ({
        getEmployees: builder.query({
            query: () => ({
                url:'/employee'
            }),
            providesTags:['Employees'],
            keepUnusedDataFor: 2
        }),
        updateEmployee: builder.mutation({
            query: (id, employee) => ({
                url: `/employee/${id}`,
                method: 'PUT',
                body: employee
            }),
            invalidatesTags: ['Employees']
        }),
        addEmployee: builder.mutation({
            query: (employee) => ({
                url: `/employee`,
                method: 'POST',
                body: employee
            }),
            invalidatesTags: ['Employees']
        })
    }),
});

export const {
    useGetEmployeesQuery,
    useUpdateEmployeeMutation,
    useAddEmployeeMutation
} = employeesApiSlice;

希望这对你有所帮助。

英文:

In EditEmployee component after editing when I click on "Save Changes" button the updateEmployee method for some reason does not send body in PUT request.

What am I doing wrong here?

EditEmployee.js

import React, { useState } from &#39;react&#39;;
import { useUpdateEmployeeMutation } from &quot;./employeesApiSlice&quot;;
function EditEmployee(props) {
const [updateEmployee] = useUpdateEmployeeMutation();
const [updatedFirstName, setUpdatedFirstName] = useState(props.employee.firstName);
const [updatedLastName, setUpdatedLastName] = useState(props.employee.lastName);
const [updatedPosition, setUpdatedPosition] = useState(props.employee.position);
const jobPositions = [&#39;Labor&#39;, &#39;Worker&#39;, &#39;Supervisor&#39;, &#39;Manager&#39;, &#39;HR&#39;, &#39;Director&#39;, &#39;CEO&#39;]
.map((jobPosition, i) =&gt; (
&lt;Col key={i}&gt;
&lt;Form.Group className=&quot;mb-3&quot; controlId={jobPosition.toLowerCase()}&gt;
&lt;Form.Check
type=&quot;radio&quot;
name=&quot;position&quot;
label={jobPosition}
value={jobPosition.toLowerCase()}
defaultChecked={props.employee.position.toLowerCase() === jobPosition.toLowerCase()}
onChange={e =&gt; setUpdatedPosition(e.target.value)}
/&gt;
&lt;/Form.Group&gt;
&lt;/Col&gt;
));
function handleSaveChanges() {
const employee = {
firstName: updatedFirstName,
lastName: updatedLastName,
position: updatedPosition
}
updateEmployee(props.employee.id, employee)
}
return (
&lt;&gt;
&lt;Form&gt;
&lt;Form.Group className=&quot;mb-3&quot; controlId=&quot;formFirstName&quot;&gt;
&lt;Form.Label&gt;First Name&lt;/Form.Label&gt;
&lt;Form.Control type=&quot;text&quot; defaultValue={updatedFirstName} onChange={e =&gt; setUpdatedFirstName(e.target.value)} /&gt;
&lt;/Form.Group&gt;
&lt;Form.Group className=&quot;mb-3&quot; controlId=&quot;formLastName&quot;&gt;
&lt;Form.Label&gt;Last Name&lt;/Form.Label&gt;
&lt;Form.Control type=&quot;text&quot; defaultValue={updatedLastName} onChange={e =&gt; setUpdatedLastName(e.target.value)} /&gt;
&lt;/Form.Group&gt;
&lt;Container&gt;
&lt;Row&gt;
{jobPositions}
&lt;/Row&gt;
&lt;/Container&gt;
&lt;/Form&gt;
&lt;Button variant=&quot;success&quot; onClick={() =&gt; handleSaveChanges()}&gt;
Save Changes
&lt;/Button&gt;
&lt;/&gt;
);
}
export default EditEmployee;

employeeApiSlice.js

import { apiSlice } from &quot;../../app/api/apiSlice&quot;;
export const employeesApiSlice = apiSlice.injectEndpoints({
tagTypes: [&#39;Employees&#39;],
endpoints: (builder) =&gt; ({
getEmployees: builder.query({
query: () =&gt; ({
url:&#39;/employee&#39;
}),
providesTags:[&#39;Employees&#39;],
keepUnusedDataFor: 2
}),
updateEmployee: builder.mutation({
query: (id, employee) =&gt; ({
url: `/employee/${id}`,
method: &#39;PUT&#39;,
body: employee
}),
invalidatesTags: [&#39;Employees&#39;]
}),
addEmployee: builder.mutation({
query: (employee) =&gt; ({
url: `/employee`,
method: &#39;POST&#39;,
body: employee
}),
invalidatesTags: [&#39;Employees&#39;]
})
}),
});
export const {
useGetEmployeesQuery,
useUpdateEmployeeMutation,
useAddEmployeeMutation
} = employeesApiSlice;

答案1

得分: 1

"query"端点的query回调接受一个单一参数。

参见:Mutation端点定义

如果需要传递多个值,它们应该被打包在一个对象中。

示例:

updateEmployee: builder.mutation({
  query: ({ id, employee }) => ({
    url: `/employee/${id}`,
    method: 'PUT',
    body: employee
  }),
  invalidatesTags: ['Employees']
}),
function handleSaveChanges() {
  const employee = {
    firstName: updatedFirstName,
    lastName: updatedLastName,
    position: updatedPosition
  };

  updateEmployee({ id: props.employee.id, employee });
}
英文:

The query callback of an endpoint takes a single argument.

See: Mutation Endpoint Definition

> export type MutationDefinition<
> QueryArg,
> BaseQuery extends BaseQueryFn,
> TagTypes extends string,
> ResultType,
> ReducerPath extends string = string,
> Context = Record<string, any>
> > = {
> query(arg: QueryArg): BaseQueryArg<BaseQuery> <---- Single Argument
>
> /* either query or queryFn can be present, but not both simultaneously /
> queryFn(
> arg: QueryArg,
> api: BaseQueryApi,
> extraOptions: BaseQueryExtraOptions<BaseQuery>,
> baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>
> ): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>
>
> /
transformResponse only available with query, not queryFn /
> transformResponse?(
> baseQueryReturnValue: BaseQueryResult<BaseQuery>,
> meta: BaseQueryMeta<BaseQuery>,
> arg: QueryArg
> ): ResultType | Promise<ResultType>
>
> /
transformErrorResponse only available with query, not queryFn */
> transformErrorResponse?(
> baseQueryReturnValue: BaseQueryError<BaseQuery>,
> meta: BaseQueryMeta<BaseQuery>,
> arg: QueryArg
> ): unknown
>
> extraOptions?: BaseQueryExtraOptions<BaseQuery>
>
> invalidatesTags?: ResultDescription<TagTypes, ResultType, QueryArg>
>
> onQueryStarted?(
> arg: QueryArg,
> {
> dispatch,
> getState,
> extra,
> requestId,
> queryFulfilled,
> getCacheEntry,
> }: MutationLifecycleApi
> ): Promise<void>
>
> onCacheEntryAdded?(
> arg: QueryArg,
> {
> dispatch,
> getState,
> extra,
> requestId,
> cacheEntryRemoved,
> cacheDataLoaded,
> getCacheEntry,
> }: MutationCacheLifecycleApi
> ): Promise<void>
> }

If you need to pass multiple values they should be packed in an object.

Example:

updateEmployee: builder.mutation({
query: ({ id, employee }) =&gt; ({
url: `/employee/${id}`,
method: &#39;PUT&#39;,
body: employee
}),
invalidatesTags: [&#39;Employees&#39;]
}),
function handleSaveChanges() {
const employee = {
firstName: updatedFirstName,
lastName: updatedLastName,
position: updatedPosition
};
updateEmployee({ id: props.employee.id, employee });
}

huangapple
  • 本文由 发表于 2023年1月9日 08:35:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75052282.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定