Reputation: 1328
I am using Ant-design in my React project so I am using tags given by them in my own project Tags
So here is my code
Parent component
export default function FormSection() {
const tagsData = ['1','2 ','3']
const tagsData1 = ['a','b ','c']
const getValueofTag = value => {
console.log(value)
}
return (
<div className="form-section">
<form>
<div className="selectable-tags-mortgage">
{tagsData.map(tag => (
<CheckableAntTag tag={tag} getValueofTag={getValueofTag} />
))}
</div>
<div className="selectable-tags-holders">
{tagsData1.map(tag => (
<CheckableAntTag tag={tag} getValueofTag={getValueofTag} />
))}
</div>
</form>
</div>
)
}
CheckableAntTag is a child component as I want to make this component reusable so I made this is a separate component
Child Component
import React, { useState, useEffect } from 'react' import { Tag } from 'antd' import PropTypes from 'prop-types'
export default function CheckableAntTag({ tag, getValueofTag }) {
const [selectedTags, setSelectedTags] = useState('')
const { CheckableTag } = Tag
const handleChange1 = (tag, checked) => {
const nextSelectedTags = checked ? [tag] : selectedTags.filter(t => t !== tag)
setSelectedTags(nextSelectedTags)
getValueofTag(nextSelectedTags)
}
return (
<CheckableTag
style={{
backgroundColor: selectedTags.indexOf(tag) > -1 ? 'red' : 'orange'
}}
key={tag}
checked={selectedTags.indexOf(tag) > -1 ? true : false}
onChange={checked => handleChange1(tag, checked)}>
{tag}
</CheckableTag>
)
}
CheckableAntTag.propTypes = {
tag: PropTypes.object,
getValueofTag: PropTypes.func
}
With this logic, the issue I am facing is when I click on the tag the value gets set in the state and the background colour changes and then when I click on other tags the value does get set in the state(replacing the previous) but the background colour still remains the same.
Please refer to the screenshot below to get more clear what issue I am facing
In the screenshot u can see first I click on "a" state gets to ["a"] after that when I click on "c" state gets set to "c" but "a" is also highlighted at this point which shouldn't be the case
Upvotes: 1
Views: 841
Reputation: 777
You need to have the state logic in the parent component and not in the reusable component unless you make it a list generator component, if you want just one tag at a time no need to store it in an array just use a string. You can figure out rest of the improvements on your own out of this
const tagsData = ["1", "2 ", "3"];
const tagsData1 = ["a", "b ", "c"];
export default function FormSection() {
const [selectedMortgageTag, setSelectedMortgageTag] = useState("");
const [selectedHolderTag, setSelectedHolderTag] = useState("");
return (
<div className="form-section">
<form>
<div className="selectable-tags-mortgage">
{tagsData.map((tag) => (
<CheckableAntTag
tag={tag}
setValue={setSelectedMortgageTag}
value={selectedMortgageTag}
/>
))}
</div>
<div className="selectable-tags-holders">
{tagsData1.map((tag) => (
<CheckableAntTag
tag={tag}
setValue={setSelectedHolderTag}
value={selectedHolderTag}
/>
))}
</div>
</form>
</div>
);
}
const { CheckableTag } = Tag;
function CheckableAntTag({ tag, value, setValue }) {
return (
<CheckableTag
style={{
backgroundColor: tag === value ? "red" : "orange"
}}
key={tag}
checked={tag === value}
onClick={() => setValue(tag)}
>
{tag}
</CheckableTag>
);
}
CheckableAntTag.propTypes = {
tag: PropTypes.object,
value: PropTypes.string,
setValue: PropTypes.func
};
Upvotes: 1