Reputation: 691
I am creating a react app where I want to output possible diseases if the symptoms button is clicked.
state = {
user_symptoms = [],
user_possible_disease = []
}
Disease = {
'aids': ['fever', 'cough', 'dysentery'],
'corona': ['fever', 'cough', 'breathe_problem'],
'heart_attack': ['angina', 'pain', 'head_ache'],
[A bunch of objects like this]
}
render() {
return(
<div>
<p>{{this.state.user_possible_disease.map((key, index) => {
return <h2 key={index}>{Object.keys(key)}</h2>
})}}</p>
<button value='cough' className='unclicked' />
<button value='angina' className='unclicked' />
<button value='pain' className='unclicked' />
<button value='breathe_problem' className='unclicked' />
</div>
)
}
So if I click any button of the symptoms, then the possible disease object with any of those symptoms will be added in the user_possible_dissease
Suppose I have clicked on the cough
button so the user_possible_disease: [{'aids': ['fever', 'cough', 'dysentery'],
'corona': ['fever', 'cough', 'breathe_problem'],}]
will be like this and if I unclick the button the possible diseases will be gone from the state.
Upvotes: 0
Views: 960
Reputation: 181
First, I'd recommend storing the selected diseases in a JSON, instead of array.
state = {
user_possible_disease = {}
}
Then define the onButtonClick function:
onButtonClick (e) {
const disease = e.target.value;
const isActive = this.state.user_possible_disease[disease];
if (isActive) {
// Remove this disease from state;
const { [disease]: _, ...restDiseases } = this.state.user_possible_disease;
this.setState(restDiseases);
} else {
// Add this disease to state;
this.setState({
...this.state.user_possible_disease,
[disease]: Disease[disease]
})
}
}
And at last attach the onButtonClick function to each button:
<button
value='cough'
onClick={this.onButtonClick}
className={this.state.user_possible_disease['cough'] ? 'clicked' : 'unclicked'} />
Also one tip: Try not to duplicate any code/values. For example in the moment user clicks the button, we store the very same array of symptoms into the state. And that array exists both in the Disease constant AND in the state. A better practice would be just to store the selected disease keys in thee state, like: ['aids', 'corona'], and then when user submits the form, to generate they request payload, by looping the selected diseases (from state), find their related symptoms and push them to they payload. This way you lift off the component's state, e.g. it holds less data.
Upvotes: 1
Reputation: 39250
I guess you wanted to show diseases for given symptoms. You can do the following:
class App extends React.Component {
state = {
user_symptoms: [],
user_possible_disease: [],
};
Disease = {
aids: ['fever', 'cough', 'dysentery'],
corona: ['fever', 'cough', 'breathe_problem'],
heart_attack: ['angina', 'pain', 'head_ache'],
};
toggleSymptom = (e) => {
let user_symptoms = this.state.user_symptoms;
if (user_symptoms.includes(e.target.value)) {
//we already have this symptom then remove it
user_symptoms = user_symptoms.filter(
(s) => s !== e.target.value
);
} else {
//we dont have the symptom so add it
user_symptoms = [...user_symptoms, e.target.value];
}
this.setState({
user_symptoms,
user_possible_disease: user_symptoms.length //do we have symptoms
? Object.entries(this.Disease) //look for deseases
.filter(([, diseaseSymptom]) =>
user_symptoms.every((
s //all symptoms are symptoms of disease
) => diseaseSymptom.includes(s))
)
.map(([key]) => key) //only need key of the object
: [],
});
};
render() {
return (
<div>
<ul>
{this.state.user_possible_disease.map((d) => (
<li key={d}>{d}</li>
))}
</ul>
<button
value="cough"
className="unclicked"
onClick={this.toggleSymptom}
>
cough
</button>
<button
value="angina"
className="unclicked"
onClick={this.toggleSymptom}
>
angina
</button>
<button
value="pain"
className="unclicked"
onClick={this.toggleSymptom}
>
pain
</button>
<button
value="breathe_problem"
className="unclicked"
onClick={this.toggleSymptom}
>
breathe problem
</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1
Reputation: 18739
Add an onClick
event to the button(s) and then set the right diseases based on the value of the clicked button.
const Disease = {
corona: ["fever", "cough", "breathe_problem"]
};
class App extends React.Component {
state = {
user_possible_disease: []
};
// This function will be called for all buttons
setPossibleDiseases = (event) => {
// The Disease[event.target.value] fetches the diseases from the Diseases object
this.setState({
user_possible_disease: Disease[event.target.value]
});
};
render() {
return (
<div>
<div>
{this.state.user_possible_disease.map((disease, index) => {
return <h2 key={index}>{disease}</h2>;
})}
</div>
<button
value="corona"
className="unclicked"
onClick={this.setPossibleDiseases}
>
Corona
</button>
</div>
);
}
}
In your example you have a {
to much in {{this.state.user_poss....
and also an h2
cannot/should not be inside a p
.
Upvotes: 0