React-Select 过滤器不适用于 React Hook
React-Select filter not working on react hook
我正在尝试让问题过滤在我的 React 应用程序上运行。我遇到的问题是问题没有过滤掉。例如,当我从第一个框中单击第一个问题时,第二个框不会过滤掉该问题。状态似乎有问题,但我不完全确定,因为状态似乎在钩子中设置得很好。
如图所示,问题应该被过滤掉,但实际上并没有
代码
const [questionVals, setQuestionVals] = useState([{value: "", label: "Choose..."}, {value: "", label: "Choose..."}, {value: "", label: "Choose..."}])
const [securityQuestions, setSecurityQuestions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const [availableOptions, setAvailableOptions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const handleQuestionValChange = (option, index) => {
const newQuestionVals = questionVals
newQuestionVals[index] = option
setQuestionVals(newQuestionVals)
getAvailableOptions()
console.log(newQuestionVals)
}
const getAvailableOptions = () => {
const availableOptionsLeft = securityQuestions
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.indexOf(questionOption) === -1
})
console.log(newOptions)
setAvailableOptions(newOptions)
}
<Form.Label htmlFor="question1">Question 1</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[0]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 0)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionOne" type="securityQuestionOne" name="securityQuestionOne" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionOneAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-3"></div>
<Form.Label htmlFor="question2">Question 2</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[1]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 1)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionTwo" type="securityQuestionTwo" name="securityQuestionTwo" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionTwoAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class = "mt-3"></div>
<Form.Label htmlFor="question3">Question 3</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[2]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 2)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionThree" type="securityQuestionThree" name="securityQuestionThree" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionThreeAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-5"></div>
{error &&
error.map((err, i) =>
<Alert className="mt-3" variant='danger' key={i}>{err}</Alert>
)
}
<Button size="lg" className="w-100 mb-3" type="submit" ref={signupButtonRef}>{t('signup')}</Button>
</Form>
在 getAvailableOptions
中,您使用的 indexOf
会导致对对象执行 Strict Equality Comparison,从而通过引用进行比较。由于您的值来自两个分别实例化的不同数组,因此对于相同的问题,引用将不同。
一个可能的解决方案是改用 find
并使用问题的 value
:
进行比较
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.find(
question => question.value === questionOption.value
) === undefined;
})
我正在尝试让问题过滤在我的 React 应用程序上运行。我遇到的问题是问题没有过滤掉。例如,当我从第一个框中单击第一个问题时,第二个框不会过滤掉该问题。状态似乎有问题,但我不完全确定,因为状态似乎在钩子中设置得很好。
如图所示,问题应该被过滤掉,但实际上并没有
代码
const [questionVals, setQuestionVals] = useState([{value: "", label: "Choose..."}, {value: "", label: "Choose..."}, {value: "", label: "Choose..."}])
const [securityQuestions, setSecurityQuestions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const [availableOptions, setAvailableOptions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const handleQuestionValChange = (option, index) => {
const newQuestionVals = questionVals
newQuestionVals[index] = option
setQuestionVals(newQuestionVals)
getAvailableOptions()
console.log(newQuestionVals)
}
const getAvailableOptions = () => {
const availableOptionsLeft = securityQuestions
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.indexOf(questionOption) === -1
})
console.log(newOptions)
setAvailableOptions(newOptions)
}
<Form.Label htmlFor="question1">Question 1</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[0]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 0)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionOne" type="securityQuestionOne" name="securityQuestionOne" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionOneAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-3"></div>
<Form.Label htmlFor="question2">Question 2</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[1]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 1)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionTwo" type="securityQuestionTwo" name="securityQuestionTwo" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionTwoAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class = "mt-3"></div>
<Form.Label htmlFor="question3">Question 3</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[2]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 2)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionThree" type="securityQuestionThree" name="securityQuestionThree" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionThreeAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-5"></div>
{error &&
error.map((err, i) =>
<Alert className="mt-3" variant='danger' key={i}>{err}</Alert>
)
}
<Button size="lg" className="w-100 mb-3" type="submit" ref={signupButtonRef}>{t('signup')}</Button>
</Form>
在 getAvailableOptions
中,您使用的 indexOf
会导致对对象执行 Strict Equality Comparison,从而通过引用进行比较。由于您的值来自两个分别实例化的不同数组,因此对于相同的问题,引用将不同。
一个可能的解决方案是改用 find
并使用问题的 value
:
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.find(
question => question.value === questionOption.value
) === undefined;
})