各位好 最近剛學 react
配合 react-select
套件
一些需求
目前頁面長這樣:
code
npm
結構部分
function
我選了部門之後,改變了 state 拿到了正確的人員選項,但我的select 拿到正確 function 卻沒有更新成正確選項
log狀態
補充說明
隨意打個字(就算不在選項內),他就會顯示正確選項了,但刪掉又會不見...
爬了很多文章好像是說,套件內部會用 inputValue 做 filter,那我要怎麼在不打字的情況正確顯示啊
可以請問這是為什麼,還有要怎麼解決嗎
第一次發問,盡量把問題打清楚了,如果還有缺什麼資訊,可以跟我反應,感謝各位
補充完整程式碼
import { Main } from "@/layouts/main";
import AsyncSelect from "react-select/async";
import { useCallback, useMemo, useState } from "react";
const QAQ = () => {
console.count("render");
// ! 設定 dept state
const [dept, setDept] = useState<string>("0");
console.log({ dept });
// ! 員工清單
const employee = useMemo(
() => [
{ name: "a", dept: "1" },
{ name: "b", dept: "1" },
{ name: "c", dept: "2" },
{ name: "d", dept: "2" },
{ name: "x", dept: "3" },
{ name: "y", dept: "3" },
{ name: "z", dept: "3" },
],
[]
);
// ! fetch 部門的選項
async function getDeptOptions() {
return new Promise((resolve) => {
resolve([
{ label: "dept-1", value: "1" },
{ label: "dept-2", value: "2" },
{ label: "dept-3", value: "3" },
]);
});
}
// ! filter 人員的公司 拿到正確的名單
const getDeptEmployee = useCallback(
function (dept: string) {
const empInThisDept = employee.filter((e) => e.dept === dept);
return empInThisDept.map((i) => {
return { label: i.name, value: i.name };
});
},
[employee]
);
// ! fetch 人員的選項
const getEmpOptions = useCallback(
async function () {
return new Promise((resolve, reject) => {
resolve(getDeptEmployee(dept));
});
},
[dept, getDeptEmployee]
);
console.log("options", getEmpOptions());
// ! 選了部門改變 state
function handleChange(d: { label: string; value: string }) {
console.log(d);
setDept(d.value);
}
return (
<Main>
<div className='flex items-center gap-4'>
部門
<AsyncSelect
defaultOptions
loadOptions={getDeptOptions as any}
onChange={handleChange as any}
autoFocus
openMenuOnFocus
/>
人員
<AsyncSelect
defaultOptions
loadOptions={getEmpOptions as any}
autoFocus
openMenuOnFocus
/>
</div>
</Main>
);
};
感謝 馬上更新!!
最近終於有時間幫你看了。
問題很簡單,你第一層select的handleChange沒有觸發第二層Select的行為,所以只有在輸入input時才會去Load第二層的資料。
其實這樣,不如在選擇第一層資料時就把第二層資料選擇好,一併送到Component裡面,以下是我修改完的結果。
import AsyncSelect from "react-select/async";
import { useMemo, useState } from "react";
const DoubleSelect = (props) => {
const { handleChange, loadLV1Options, LV2Options } = props
return (
<div className='flex items-center gap-4'>
部門
<AsyncSelect
defaultOptions
loadOptions={loadLV1Options}
onChange={handleChange}
autoFocus
openMenuOnFocus
/>
人員
<AsyncSelect
defaultOptions = {LV2Options}
autoFocus
openMenuOnFocus
/>
</div>
);
};
const QAQ = () => {
const [dept, setDept] = useState("0");
const [emp, setEmp] = useState([])
// ! 員工清單
const employee = useMemo(
() => [
{ name: "a", dept: "1" },
{ name: "b", dept: "1" },
{ name: "c", dept: "2" },
{ name: "d", dept: "2" },
{ name: "x", dept: "3" },
{ name: "y", dept: "3" },
{ name: "z", dept: "3" },
],[]
);
// ! fetch 部門的選項
const getDeptOptions = async () => {
return new Promise((resolve) => {
resolve([
{ label: "dept-1", value: "1" },
{ label: "dept-2", value: "2" },
{ label: "dept-3", value: "3" },
]);
});
}
const getEmpOptions = async (__value) => {
const empInThisDept = employee.filter((e) => e.dept === __value);
return new Promise((resolve, reject) => {
resolve(
empInThisDept.map(item => {
return {label: item.name, value: item.name }
})
)
})
}
const handleChangeL1Select = (d) => {
setDept(d)
getEmpOptions(d.value)
.then(res => {
setEmp(res)
}
)
}
return(
<DoubleSelect
handleChange={handleChangeL1Select}
loadLV1Options={getDeptOptions}
LV2Options={emp}>
</DoubleSelect>
)
}
export default QAQ
非常感謝 使用起來都正常了