问题
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:
Placeholder
Input
when you select one (or multiple) value(s) then it changes for:
SingleValue
orMultiValue
Input
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