如何在 react-select 下拉列表中获取单个值
How to get single value in react-select dropdown
我正在尝试使用 react-select.
创建一个多 select 下拉指示器 (the second element shown here)
目的是在博客页面上显示所有博客 post 类别,然后仅呈现在下拉指示器中 selected 的博客 post。
标签是根据 GraphQL 查询从它们的 post 中提取的,并存储在 useState 变量“tags”和“renderedPosts”中。
添加或删除类别时,我如何简单地从下拉列表中获取值? 阅读 react-select API,我明白了这个:
getValue () => ReadonlyArray<...>
我不知道如何使用它,当我尝试在 Select.
中添加箭头函数作为属性时,VS Code 只是尖叫
我知道 Select 默认情况下应该有一个“值”,但如果我尝试使用它,我会得到未定义的值。
我不知道映射到默认值是否有问题,或者它是否与 ContextProvider 有任何关系(这是必要的)。还有其他属性我也无法使用,比如 maxMenuHeight(应该是一个数字)。
请允许我分享我的代码(您可以忽略 useEffect):
export default function Blog({ data }) {
const { posts } = data.blog
const [tags, setTags] = useState([])
const [renderedPosts, setRenderedPosts] = useState([])
// Context necessary to render default options in react-select
const TagsContext = createContext();
// setting all tags (for dropdown-indicator) and rendered posts below the dropdown (initially these two will be the same)
useEffect(() => {
const arr = [];
data.blog.posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!arr.some(index => index.value === tag)) {
arr.push({ value: tag, label: tag })
}
})
});
setTags([arr]);
setRenderedPosts([arr]);
}, []);
function changeRenderedPosts(value???){
setRenderedPosts(value???)
}
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
defaultValue={tags.map(tag => tag) }
isMulti
name="tags"
options={tags}
className="basic-multi-select"
classNamePrefix="select"
// HOW DO I PASS THE VALUE OF THE ADDED/DELETED OPTION?
onChange={() => changeRenderedPosts(value???)}
maxMenuHeight= {1}
/>
</TagsContext.Provider>
// posts to be rendered based on renderedPosts value
{posts.map(post => {
编辑:我现在最接近的解决方案如下:
function changeRenderedTags(options){
console.log(options) //logs the remaining options
setRenderedTags(options) //blocks the change of the dropdown elements
}
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
...
onChange={(tagOptions) => changeRenderedTags(tagOptions)}
我单击以从下拉列表中删除一个选项,然后在“tagOptions”中获得其他两个选项。但是如果我尝试更改“renderedTags”,状态更新将被阻止。我觉得这莫名其妙,因为“setRenderedTags”与下拉列表或其数据的呈现无关!
如果 isMulti
选项为真,您会从 onChange 回调中获得选项数组(这里是 tags
)。所以我想您可以设置新标签并根据所选标签呈现过滤后的帖子,如下所示?
const renderedPosts = posts.filter(post => post.tags.some(tag => tags.includes(tag)))
...
onChange={selectedTags => {
setTags(selectedTags ? selectedTags.map(option => option.value) : [])
}}
...
我终于解决了 - 我不知道这是否是最好的解决方案,但它确实有效!在这里分享它以防其他人处于完全相同的情况,或者如果您只是好奇。欢迎建设性的批评。
export default function Blog({ data }) {
const { posts } = data.blog
const [tags, setTags] = useState([])
const [renderedTags, setRenderedTags] = useState([])
const TagsContext = createContext();
useEffect(() => {
const arr = [];
posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!arr.some(index => index.value === tag)) {
arr.push({ value: tag, label: tag })
}
})
});
setTags([...arr]);
}, [posts]);
useEffect(() => {
setRenderedTags([...tags]);
}, [tags])
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
defaultValue={tags}
isMulti
name="tags"
options={tags}
className="basic-multi-select"
classNamePrefix="select"
onChange={(tagOptions) => setRenderedTags(tagOptions ? tagOptions.map(option => option) : [])}
value={renderedTags}
/>
</TagsContext.Provider>
{posts.map(post =>
(post.frontmatter.tags.some(i => renderedTags.find(j => j.value === i))) ?
<article key={post.id}>
<Link to={post.fields.slug}>
<h2>{post.frontmatter.title}</h2>
<p>{post.frontmatter.introduction}</p>
</Link>
<small>
{post.frontmatter.author}, {post.frontmatter.date}
</small>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>
: null
)}
</div>
</Layout>
)
}
我正在尝试使用 react-select.
创建一个多 select 下拉指示器 (the second element shown here)目的是在博客页面上显示所有博客 post 类别,然后仅呈现在下拉指示器中 selected 的博客 post。
标签是根据 GraphQL 查询从它们的 post 中提取的,并存储在 useState 变量“tags”和“renderedPosts”中。
添加或删除类别时,我如何简单地从下拉列表中获取值? 阅读 react-select API,我明白了这个:
getValue () => ReadonlyArray<...>
我不知道如何使用它,当我尝试在 Select.
中添加箭头函数作为属性时,VS Code 只是尖叫我知道 Select 默认情况下应该有一个“值”,但如果我尝试使用它,我会得到未定义的值。
我不知道映射到默认值是否有问题,或者它是否与 ContextProvider 有任何关系(这是必要的)。还有其他属性我也无法使用,比如 maxMenuHeight(应该是一个数字)。
请允许我分享我的代码(您可以忽略 useEffect):
export default function Blog({ data }) {
const { posts } = data.blog
const [tags, setTags] = useState([])
const [renderedPosts, setRenderedPosts] = useState([])
// Context necessary to render default options in react-select
const TagsContext = createContext();
// setting all tags (for dropdown-indicator) and rendered posts below the dropdown (initially these two will be the same)
useEffect(() => {
const arr = [];
data.blog.posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!arr.some(index => index.value === tag)) {
arr.push({ value: tag, label: tag })
}
})
});
setTags([arr]);
setRenderedPosts([arr]);
}, []);
function changeRenderedPosts(value???){
setRenderedPosts(value???)
}
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
defaultValue={tags.map(tag => tag) }
isMulti
name="tags"
options={tags}
className="basic-multi-select"
classNamePrefix="select"
// HOW DO I PASS THE VALUE OF THE ADDED/DELETED OPTION?
onChange={() => changeRenderedPosts(value???)}
maxMenuHeight= {1}
/>
</TagsContext.Provider>
// posts to be rendered based on renderedPosts value
{posts.map(post => {
编辑:我现在最接近的解决方案如下:
function changeRenderedTags(options){
console.log(options) //logs the remaining options
setRenderedTags(options) //blocks the change of the dropdown elements
}
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
...
onChange={(tagOptions) => changeRenderedTags(tagOptions)}
我单击以从下拉列表中删除一个选项,然后在“tagOptions”中获得其他两个选项。但是如果我尝试更改“renderedTags”,状态更新将被阻止。我觉得这莫名其妙,因为“setRenderedTags”与下拉列表或其数据的呈现无关!
如果 isMulti
选项为真,您会从 onChange 回调中获得选项数组(这里是 tags
)。所以我想您可以设置新标签并根据所选标签呈现过滤后的帖子,如下所示?
const renderedPosts = posts.filter(post => post.tags.some(tag => tags.includes(tag)))
...
onChange={selectedTags => {
setTags(selectedTags ? selectedTags.map(option => option.value) : [])
}}
...
我终于解决了 - 我不知道这是否是最好的解决方案,但它确实有效!在这里分享它以防其他人处于完全相同的情况,或者如果您只是好奇。欢迎建设性的批评。
export default function Blog({ data }) {
const { posts } = data.blog
const [tags, setTags] = useState([])
const [renderedTags, setRenderedTags] = useState([])
const TagsContext = createContext();
useEffect(() => {
const arr = [];
posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!arr.some(index => index.value === tag)) {
arr.push({ value: tag, label: tag })
}
})
});
setTags([...arr]);
}, [posts]);
useEffect(() => {
setRenderedTags([...tags]);
}, [tags])
return (
<Layout>
<div>
<h1>My blog posts</h1>
<TagsContext.Provider value={{ tags }}>
<Select
defaultValue={tags}
isMulti
name="tags"
options={tags}
className="basic-multi-select"
classNamePrefix="select"
onChange={(tagOptions) => setRenderedTags(tagOptions ? tagOptions.map(option => option) : [])}
value={renderedTags}
/>
</TagsContext.Provider>
{posts.map(post =>
(post.frontmatter.tags.some(i => renderedTags.find(j => j.value === i))) ?
<article key={post.id}>
<Link to={post.fields.slug}>
<h2>{post.frontmatter.title}</h2>
<p>{post.frontmatter.introduction}</p>
</Link>
<small>
{post.frontmatter.author}, {post.frontmatter.date}
</small>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>
: null
)}
</div>
</Layout>
)
}