i build this div element here , which at the end has a " " button and a "x" button . The plus button adds the same div just below it and the x or clear button removes it . Now how can i render the same div when clicking plus button or when clicking x , i tried multiple ways but i couldn't do it , this is my code. One way that i think of is doing recursion but it doesn't work.
function IpRangeInput() {
const [ipRange, setIpRange] = useState<string>('');
const [inputValue, setInputValue] = useState<string>('');
const [fromValue, setFromValue] = useState<string>('');
const [toValue, setToValue] = useState<string>('');
const handleInputValue = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event?.target.value);
};
const handleAdd = () => <IpRangeInput />;
return (
<Box className={styles.inputContainer}>
<ThemeProvider theme={theme}>
<FormControl className={styles.inputContainer__select}>
<Select
defaultValue="Select"
id="select-label"
value={ipRange}
onChange={(e) => setIpRange(e.target.value)}
>
<MenuItem value="IP/CIDR">IP / CIDR</MenuItem>
<MenuItem value="Range">Range</MenuItem>
</Select>
</FormControl>
{ipRange === 'Range' ? (
<>
<span className={styles.inputContainer__text}>From</span>
<Box
className={[
styles.inputContainer__input,
styles.inputContainer__newInput,
].join(' ')}
>
<TextField
value={fromValue}
onChange={(e) => setFromValue(e.target.value)}
/>
</Box>
<span className={styles.inputContainer__text}>To</span>
<Box
className={[
styles.inputContainer__input,
styles.inputContainer__newInput,
].join(' ')}
>
<TextField
value={toValue}
onChange={(e) => setToValue(e.target.value)}
/>
</Box>
</>
) : (
<Box className={styles.inputContainer__input}>
<TextField value={inputValue} onChange={handleInputValue} />
</Box>
)}
<IconButton
className={styles.inputContainer__addButton}
onClick={handleAdd}
>
<AddIcon />
</IconButton>
<IconButton
className={styles.inputContainer__clearButton}
onClick={handleAdd}
>
<Clear />
</IconButton>
</ThemeProvider>
</Box>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
CodePudding user response:
Вам нужно хранить список блоков в родительском компоненте в стейте, например, как массив айди. Каждому блоку присваивается свой айди. И в итоге нажатие кнопок будет триггерить удаление или добавление айди в массив или из него
Ваш итоговый код:
function Parent () {
const [list, setList] = useState([0])
const handleAdd = (id) => setList(prevList => prevList.push(id 1))
const handleClear = (id) => setList(prevList => {
prevList.splice(id, 1)
return prevList
})
return (
list.map((item) => {
<IpRangeInput
key={item}
id={item}
handleAdd={handleAdd}
handleClear={handleClear}
/>
})
)
}
function IpRangeInput({ handleAdd, handleClear, id }) {
const [ipRange, setIpRange] = useState<string>('');
const [inputValue, setInputValue] = useState<string>('');
const [fromValue, setFromValue] = useState<string>('');
const [toValue, setToValue] = useState<string>('');
const handleInputValue = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event?.target.value);
};
const handleAdd = () => handleAdd(id)
const handleClear = () => handleAdd(id)
return (
<Box className={styles.inputContainer}>
<ThemeProvider theme={theme}>
<FormControl className={styles.inputContainer__select}>
<Select
defaultValue="Select"
id="select-label"
value={ipRange}
onChange={(e) => setIpRange(e.target.value)}
>
<MenuItem value="IP/CIDR">IP / CIDR</MenuItem>
<MenuItem value="Range">Range</MenuItem>
</Select>
</FormControl>
{ipRange === 'Range' ? (
<>
<span className={styles.inputContainer__text}>From</span>
<Box
className={[
styles.inputContainer__input,
styles.inputContainer__newInput,
].join(' ')}
>
<TextField
value={fromValue}
onChange={(e) => setFromValue(e.target.value)}
/>
</Box>
<span className={styles.inputContainer__text}>To</span>
<Box
className={[
styles.inputContainer__input,
styles.inputContainer__newInput,
].join(' ')}
>
<TextField
value={toValue}
onChange={(e) => setToValue(e.target.value)}
/>
</Box>
</>
) : (
<Box className={styles.inputContainer__input}>
<TextField value={inputValue} onChange={handleInputValue} />
</Box>
)}
<IconButton
className={styles.inputContainer__addButton}
onClick={handleAdd}
>
<AddIcon />
</IconButton>
<IconButton
className={styles.inputContainer__clearButton}
onClick={handleClear}
>
<Clear />
</IconButton>
</ThemeProvider>
</Box>
);
}