问题描述
我在下面的代码底部有一个自动保存组件,它接收一个 saveData 属性,它是表值的状态,当编辑字段时,这个状态会在 onblur 上更新。现在我想获取该 saveData 并将其与 onblur 之后的先前状态进行比较,因此我只获取更改的键值并运行突变以保存它们。否则我将不得不对每个值运行一个突变,并且一旦表已满,将会有很多。
提前感谢您的帮助。
我正在尝试在这里比较旧状态和新状态,所以这可能是一个更好的起点。
这是我目前的代码
const DECOR_VALUES = gql`
query GetDecorValues($id: ID!) {
findUserByID(id: $id) {
decor {
data {
purchaseDate
description
alterations
cost
pieces
category
purchaser
image
itemNum
_id
}
}
}
}
`;
const UPDATE_DECOR_DOC = gql`
mutation UpdateDecorDoc(
# $ownerID: ID!
$description: String!
$pieces: Int!
$purchaser: String!
$alterations: Boolean!
$cost: Int!
$purchaseDate: Date!
$category: String!
$image: String!
$itemNum: Int!
) {
updateDecor(
data: {
description: $description
pieces: $pieces
purchaser: $purchaser
alterations: $alterations
cost: $cost
purchaseDate: $purchaseDate
category: $category
image: $image
itemNum: $itemNum
# owner: { connect: $ownerID }
}
) {
description
}
}
`;
const Styles = styled.div`
padding: 1rem;
table {
border-spacing: 0;
border: 1px solid black;
tr {
:last-child {
td {
border-bottom: 0;
}
}
}
th,td {
margin: 0;
padding: 0.5rem;
border-bottom: 1px solid black;
border-right: 1px solid black;
:last-child {
border-right: 0;
}
input {
font-size: 1rem;
padding: 0;
margin: 0;
border: 0;
}
&:hover {
background: lightpink;
}
}
}
.pagination {
padding: 0.5rem;
}
`;
// Create an editable cell renderer
const EditableCell = ({
value: initialValue,row: { index },column: { id },updateMyData,// This is a custom function that we supplied to our table instance
}) => {
// We need to keep and update the state of the cell normally
const [value,setValue] = React.useState(initialValue);
const onChange = (e) => {
setValue(e.target.value);
};
const onChangeDate = (e) => {
setValue(e);
};
const onChangeCheck = (e) => {
setValue(e.target.checked);
};
// We'll only update the external data when the input is blurred
const onBlur = () => {
updateMyData(index,id,value);
};
// If the initialValue is changed external,sync it up with our state
React.useEffect(() => {
setValue(initialValue);
},[initialValue]);
if (id === "col3") {
return (
<input
type="checkBox"
defaultChecked={value}
onChange={onChangeCheck}
onBlur={onBlur}
/>
);
}
if (id === "col1") {
return (
<ReactDatePicker
onCalendarClose={onBlur}
selected={new Date(value)}
onChange={onChangeDate}
/>
);
}
return <input value={value} onChange={onChange} onBlur={onBlur} />;
};
// Set our editable cell renderer as the default Cell renderer
const defaultColumn = {
Cell: EditableCell,};
const fetcher = (url) => fetch(url).then((r) => r.json());
export default function DecorData() {
const { data: user,error: userError } = useSWR("/api/user",fetcher);
const { data: cookieData,error: cookieError } = useSWR(
"/api/cookie",fetcher
);
var cookieBearer = `Bearer ${cookieData}`;
if (!user || !cookieData) return <p>Loading</p>;
if (userError) return <p>{userError.message}</p>;
if (cookieError) return <p>{cookieError.message}</p>;
return (
<Layout>
<h1>View your Decor Catalog Table Here</h1>
{user && cookieBearer && (
<Table user={user} cookieBearer={cookieBearer} />
)}
</Layout>
);
}
const Table = ({ user,cookieBearer }) => {
const { loading,error,data: decorData } = useQuery(DECOR_VALUES,{
variables: { id: user.id },context: {
headers: {
authorization: cookieBearer,},});
const massaged = decorData?.findUserByID?.decor?.data?.map((item) => {
var col = Object.values(item);
console.log("item");
console.log(decorData);
console.log("item");
return col.map((colItem,i) => {
return { [`col${i}`]: colItem };
});
});
const massaged1 = decorData?.findUserByID?.decor?.data?.map((item,int) => {
var col = Object.keys(item);
return col?.map((colItem,i) => {
console.log(colItem);
if (colItem === "image") {
return {
Header: colItem,accessor: `col${i}`,Cell: ({ cell: { value } }) => <ImageComp value={value} />,};
}
return {
Header: colItem,};
});
});
const result = massaged?.map((a) => Object.assign({},...a));
if (loading) return <p>Loading</p>;
if (error) return <p>{error.message}</p>;
if (!decorData) return <p>No Decord Data</p>;
return (
<>
{result && massaged1 && <TryThis cookieBearer={cookieBearer} result={result} massaged1={massaged1} />}
</>
);
};
const ImageComp = ({ value }) => {
return (
<>
<img src={value} width="400" />
<button>Replace Image</button>
</>
);
};
function TryThis({ result,massaged1,cookieBearer }) {
const [data,setData] = React.useState(result); //bad naming here
// const [originalData] = React.useState(data)
const [skipPageReset,setSkipPageReset] = React.useState(false);
const updateMyData = (rowIndex,columnId,value) => {
// We also turn on the flag to not reset the page
setSkipPageReset(true);
setData((old) => {
// console.log(old);
return old.map((row,index) => {
if (index === rowIndex) {
return {
...old[rowIndex],[columnId]: value,};
}
return row;
});
});
};
// After data chagnes,we turn the flag back off
// so that if data actually changes when we're not
// editing it,the page is reset
React.useEffect(() => {
setSkipPageReset(false);
},[data]);
return (
<>
{/* {result && massaged1 && (
<TableRendered result={result} massaged1={massaged1} />
)} */}
{data && result && massaged1 && (
<Styles>
{/* <button onClick={resetData}>Reset Data</button> */}
<Table1
columns={massaged1[0]}
data={data}
updateMyData={updateMyData}
skipPageReset={skipPageReset}
cookieBearer={cookieBearer}
/>
</Styles>
)}
</>
);
}
function Table1({ columns,data,skipPageReset,cookieBearer }) {
// For this example,we're using pagination to illustrate how to stop
// the current page from resetting when our data changes
// Otherwise,nothing is different here.
const {
getTableProps,getTableBodyProps,headerGroups,prepareRow,page,canPrevIoUsPage,canNextPage,pageOptions,pageCount,gotoPage,nextPage,prevIoUsPage,setPageSize,state: { pageIndex,pageSize },} = useTable(
{
columns,defaultColumn,// use the skipPageReset option to disable page resetting temporarily
autoResetPage: !skipPageReset,// updateMyData isn't part of the API,but
// anything we put into these options will
// automatically be available on the instance.
// That way we can call this function from our
// cell renderer!
updateMyData,usePagination
);
// Render the UI for your table
return (
<>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row,i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
<div className="pagination">
<button onClick={() => gotoPage(0)} disabled={!canPrevIoUsPage}>
{"<<"}
</button>{" "}
<button onClick={() => prevIoUsPage()} disabled={!canPrevIoUsPage}>
{"<"}
</button>{" "}
<button onClick={() => nextPage()} disabled={!canNextPage}>
{">"}
</button>{" "}
<button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
{">>"}
</button>{" "}
<span>
Page{" "}
<strong>
{pageIndex + 1} of {pageOptions.length}
</strong>{" "}
</span>
<span>
| Go to page:{" "}
<input
type="number"
defaultValue={pageIndex + 1}
onChange={(e) => {
const page = e.target.value ? Number(e.target.value) - 1 : 0;
gotoPage(page);
}}
style={{ width: "100px" }}
/>
</span>{" "}
<select
value={pageSize}
onChange={(e) => {
setPageSize(Number(e.target.value));
}}
>
{[10,20,30,40,50].map((pageSize) => (
<option key={pageSize} value={pageSize}>
Show {pageSize}
</option>
))}
</select>
</div>
<pre>
<code>
{JSON.stringify(
{
data,null,2
)}
</code>
</pre>
{cookieBearer&& <AutoSave cookieBearer={cookieBearer} saveData={data} />}
</>
);
}
function AutoSave({ saveData,cookieBearer }) {
const [saving,setSaving] = useState(false);
const [
updateDecorDoc,{ data: docData,loading: saving },] = useMutation(UPDATE_DECOR_DOC,{
context: {
headers: {
authorization: cookieBearer,});
const debounceSave = useCallback(
debounce(async (saveData) => {
console.log("save data");
console.log(saveData);
console.log("save data");
})
);
useEffect(() => {
if (saveData) {
debounceSave(saveData);
}
},[saveData,debounceSave]);
return null
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)