问题
We have a use case where we have to render multiple different versions of the value container for the multiselect dropdown depending on how many options are selected. The code snippet below shows one of the cases. Another version of this renders a <SingleValue /> instead of placeholder.
<ValueContainer {...props}>
<Placeholder {...props}>
{!props.selectProps.inputValue && `${length} selected`}
</Placeholder>
{children[1]}
</ValueContainer>
This seems to be working well, however we lose keyboard navigation upon selection of one of the options. Am I forgetting to pass certain props or a ref?
An example of dropped keyboard navigation for custom ValueContainers can be found here: https://codesandbox.io/s/rjvkzk1nn?from-embed
回答1:
Keyboard is not working anymore because you miss the Input component that is focused when you open the Menu.
ValueContainer has two objects when there's no value selected:
PlaceholderInput
when you select one (or multiple) value(s) then it changes for:
SingleValueorMultiValueInput
with your previous example, you were removing those two.
To keep the keyboard features, you need to keep the Input component. The following code is a combination of your code and expectation and keeping the Input component:
const ValueContainer = ({ children, ...props }) => {
const { getValue, hasValue } = props;
const newChildren = _.cloneDeep(children);
const nbValues = getValue().length;
newChildren[0] = `${nbValues} items selected`;
if (!hasValue) {
return (
<components.ValueContainer {...props}>
{children}
</components.ValueContainer>
);
}
return (
<components.ValueContainer {...props}>
{newChildren}
</components.ValueContainer>
);
};
const options = [
{ label: "label 1", value: 1 },
{ label: "label 2", value: 2 },
{ label: "label 3", value: 3 },
{ label: "label 4", value: 4 }
];
function App() {
const components = { ValueContainer };
return <Select isMulti components={components} options={options} />;
}
Live example.
回答2:
It turns out that you should put the custom value container outside the render
const CustomValueContainer: React.FC = props => (
<components.ValueContainer {...props} />
);
const App = () => {
const [selectValue, setSelectValue] = useState();
return (
<div className="App">
<Select
options={options}
value={selectValue}
closeMenuOnSelect={false}
onChange={value => setSelectValue(value)}
components={{
ValueContainer: CustomValueContainer,
}}
/>
</div>
);
};
https://github.com/JedWatson/react-select/issues/2810#issuecomment-569117980
回答3:
My solution is simple, React is not complaining about missing key prop and web browser won't hang.
imports
import Select, { components } from 'react-select'
ValueContainer function
const ValueContainer = ({ children, ...props }) => {
const length = children[0].length
let tmpChildren = [...children];
if(length >= 2){
tmpChildren[0] = `${length} languages`
}
return (
<components.ValueContainer {...props}>{tmpChildren}</components.ValueContainer>
);
};
<Select/> component
<Select
isMulti
components={{ ValueContainer }}
classNamePrefix="simplelocalize-select"
placeholder="Showing all languages"
closeMenuOnSelect={false}
/>
来源:https://stackoverflow.com/questions/58804769/react-select-losing-focus-for-custom-component-valuecontainer