我试图找到一种方法来动态调用给定字符串的函数或引用给定字符串的变量。例如:
import React, {useState} from 'react'
const array = [
{
text: 'count1',
setFunctionName: 'setCount1',
otherdata: {}
},
{
text: 'count2',
setFunctionName: 'setCount2',
otherdata: {}
}
]
const myFunction = () => {
const [count1, setCount1] = useState(0)
const [count2, setCount2] = useState(0)
return(
<div>
{array.map((item) => {
// I want to use item.text to reference the correct count variable
// I want to use item.setFunctionName to change the correct count
})}
</div>
)
}具体的用例是,我希望创建一个可重用的侧栏菜单,其中链接的数据存储在单独文件中的对象数组中。有些菜单项将有可折叠的子菜单,我需要使用状态来管理子菜单的打开和关闭。示例:
import { Button, Collapse } from 'react-bootstrap'
function Example() {
const [open, setOpen] = useState(false);
return (
<>
<Button
onClick={() => setOpen(!open)} //**I want to dynamically set this when mapping over the array**
>
click
</Button>
<Collapse in={open}> //**I want to dynamically set this when mapping over the array**
<div id="example-collapse-text">
This is example collapsed text
</div>
</Collapse>
</>
);
}发布于 2021-01-20 23:43:16
如果您不想一直移动到useReducer,那么也可以将一个对象保存到useState,而不是对每个单独的字段进行单独的useState调用:
import React, {useState} from 'react'
const array = [
{
text: 'count1',
otherdata: {}
},
{
text: 'count2',
otherdata: {}
}
]
const myFunction = () => {
// This could even be initialised based on the items in `array`
const [count, setCount] = useState({
count1: 0,
count2: 0,
});
return(
<div>
{array.map((item, index) => {
// I want to use item.text to reference the correct count variable
const countValue = count[item.text];
const updateCount = () => {
setCount((prevCount) => {
return {
...prevCount,
[item.text]: prevCount[item.text] + 1,
};
});
};
return (
<button key={index}
onClick={updateCount}
>{item.text}: { countValue }</button>
);
})}
</div>
)
}发布于 2021-01-20 22:50:29
实现这一目标的最好方法可能是使用减速机。
https://reactjs.org/docs/hooks-reference.html#usereducer
可能是这样吧?
const initialState = {count1: 0, count2: 0};
function reducer(state, action) {
switch (action.type) {
case 'setCount1':
return {
...state,
count1: action.value
};
case 'setCount2':
return {
...state,
count2: action.value
};
default:
throw new Error();
}
}
const array = [
{
text: 'count1',
setFunctionName: 'setCount1',
otherdata: {}
},
{
text: 'count2',
setFunctionName: 'setCount2',
otherdata: {}
}
]
const myFunction = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return(
<div>
{array.map((item) => {
return <a onClick={ () => dispatch({ type: item.setFunctionName, value:3 }) }>{state[item.text]} <a/>
})}
</div>
)
}发布于 2021-01-20 23:07:30
我可能错了,但听起来,如果你使用的是react引导,你可能想要使用手风琴组件,因为它可能看起来和行为更接近你要寻找的东西。但是,无论是哪种方式,在扩展时填充显示的内容都将以类似的方式处理。如果将展开的内容保存在状态对象中,则应在状态更改时自动更新。您可以在给定的数组上映射并呈现如下的JSX
<Collapse in={open}> //**I want to dynamically set this when mapping over the array**
array.map(element => {
return(
<div>
{element.text
element.setFunctionName}
</div>
)
})
</Collapse>这是这个过程的一个非常简单的应用。这里要指出的一点是,如果您在一个对象数组上映射,您可以为每个数组元素呈现JSX。这可以是任何JSX,甚至您已经创建的组件。这是相当强大的,因为这些组件可以保持自己的状态和行为,并将作为这样的行为在塌陷地区。
此外,如果数组的那些内部对象也需要具有折叠功能,则可以在映射元素中执行相同的JSX操作。天空是这方面的极限。
https://stackoverflow.com/questions/65818704
复制相似问题