Elvaleryn
Elvaleryn

Reputation: 351

How to dynamically change style by onClick with react hooks?

I am trying to make that readonly input elements become yellow when only related button is clicked. Whenever i tried i ended up making all the readonly inputs become yellow with one click. I want it to be like this for example: img1 when you choose an odd only the clicked odd's input readonly becomes yellow.

const App = () => {

    const [chosen, setChosen] = useState([1])
    const [active, setActive] = useState("gray")
    const [persons, setPersons] = useState( [
    {
      "game": "Kashima - Cerezo Osaka",
      "homeWin": 2.30,
            "draw": 3.10,
            "awayWin": 2.35,
      "id": 0
    },
    {
      "game": "K. Sanuki - Machida Zelvia",
      "homeWin": 3.60,
            "draw": 3.20,
            "awayWin": 1.65,
      "id": 1
    },
    {
            "game": "Jeonnam Dragons - Daegu",
      "homeWin": 2.50,
            "draw": 3.10,
            "awayWin": 2.10,
      "id": 2
    },
        {
            "game": "Ulsan - Suwon Sb",
      "homeWin": 1.85,
            "draw": 3.20,
            "awayWin": 2.90,
      "id": 3
    }   
  ])

    const handleOptionChange = (event) => {
    setOption(event.target.value)
  }

    const chooseOdd = (e) => {
        (e.target.style.backgroundColor === "gray") ? setActive("yellow") : setActive("gray")
        setChosen(chosen.concat(e.target.value))
    }

  return (
    <div>
        {persons.map(p => 
                <div>
                <li key={p.id}>{p.game}</li>
                <div>
                <input type="button" value={p.homeWin} onClick={chooseOdd}/>
                <input id="one" style={{backgroundColor: active}} value={p.homeWin} readOnly/>
                <input type="button" value={p.draw} onClick={chooseOdd}/>
                <input id="two" style={{backgroundColor: active}} value={p.draw} readOnly/>
                <input type="button" value={p.awayWin} onClick={chooseOdd}/>
                <input id="three" style={{backgroundColor: active}} value={p.awayWin} readOnly/>
                </div>
                </div>
            )}

Upvotes: 1

Views: 8460

Answers (3)

Omar bakhsh
Omar bakhsh

Reputation: 1056

you can add dynamic style and check conditions from the state.

 <View style={[styles.vw_chk_box, isSelected.id_3 ? { marginTop: 180 } : null]} ></View>

.

Upvotes: 0

Omar bakhsh
Omar bakhsh

Reputation: 1056

in React Native Hooks

step 1 - add a state with a value.

const [ccolor, setColor] = useState('yellow');

step 2 - add a state value to view in array [ { styl_1 } , { style_2 } ].

<View style={[styles.list_L, { backgroundColor: ccolor }]} >

step 3 - add function changes the color.

<Veiw onPress={() => { setColor('red')}}>press me </Veiw>
</View >

Upvotes: 0

Sunny
Sunny

Reputation: 952

Tested the code out. Below one works.

  1. Need to maintain state for each person element >> each button clicked
  2. Expansion operator [...persons] used to create new reference so component gets re-rendered
  3. Can add new properties to the person element using p["propertyName"]. This can be referenced using the dot operator later

enter image description here

import React, { useState } from 'react';

 const Test = () => {
 const [persons, setPersons] = useState([
{
  game: 'Kashima - Cerezo Osaka',
  homeWin: 2.30,
  draw: 3.10,
  awayWin: 2.35,
  id: 0,
},
{
  game: 'K. Sanuki - Machida Zelvia',
  homeWin: 3.60,
  draw: 3.20,
  awayWin: 1.65,
  id: 1,
},
{
  game: 'Jeonnam Dragons - Daegu',
  homeWin: 2.50,
  draw: 3.10,
  awayWin: 2.10,
  id: 2,
},
{
  game: 'Ulsan - Suwon Sb',
  homeWin: 1.85,
  draw: 3.20,
  awayWin: 2.90,
  id: 3,
 },
 ]);

const handleOptionChange = (person, option) => {
  person[option] = !person[option];
  setPersons([...persons]);
  };

return (
<div>
  {persons.map(p => (
    <div>
      <li key={p.id}>{p.game}</li>
      <div>
        <input type="button" value={p.homeWin} onClick={() => handleOptionChange(p, 'is1Selected')} />
        <input id="one" style={{ backgroundColor: p.is1Selected ? 'Yellow' : 'Gray' }} value={p.homeWin} readOnly />
        <input type="button" value={p.draw} onClick={() => handleOptionChange(p, 'is2Selected')} />
        <input id="two" style={{ backgroundColor: p.is2Selected ? 'Yellow' : 'Gray' }} value={p.draw} readOnly />
        <input type="button" value={p.awayWin} onClick={() => handleOptionChange(p, 'is3Selected')} />
        <input id="three" style={{ backgroundColor: p.is3Selected ? 'Yellow' : 'Gray' }} value={p.awayWin} readOnly />
      </div>
    </div>
  ))}
</div>
 );
};

export default Test;

Note : This is not the most optimized way to do it. You should create a new react element for each person and let the element handle the display and provide callbacks to the parent element.

Upvotes: 1

Related Questions