I am using material-table(https://material-table.com/#/) and I need to change the icon in a column according to its value. Is it possible to do it in the render option:
render: rowData => (
<div>
<i className="far fa-map-marker"></i>
<span>{rowData.locationName}</span>
</div>
)
Thanks in advance!
Go with:
render: rowData => (
<div>
<i className={`far ${rowData.value === someValue ? "first-icon" : "second-icon"}` }></i>
<span>{rowData.locationName}</span>
</div>
)
If there are more options I would suggest going with:
const valueToIconMap = { someValue: "first-icon", anotherValue: "second-icon", ...more values }
...somecode...
render: rowData => {
return <div>
<i className={`far ${valueToIconMap[rowData.value]}`}></i>
<span>{rowData.locationName}</span>
</div>
}
I dont know if I understand what you want correctly but heres what I can assume you want:
import React, { useState } from "react";
import "./App.css";
import { Add, Delete } from '#material-ui/icons'
function App(props) {
const [value, setValue] = useState("");
const test = [<Add/>,<Delete/>];
return (
<div className="App">
{test.map(e => { return e })}
</div>
);
}
export default App;
Related
I don't understand why my fetched data is not displaying.
Data is fetched properly when i check by console.log() however nothing shows up in my JSX section. Code looks alight too. Anyone have idea what is wrong here?
import React from "react";
import { useEffect, useState } from "react";
import axios from "axios";
export const ConcertLatest = () => {
const [concerts, setConcerts] = useState([]);
useEffect(() => {
const loadConcerts = async () => {
const response = await axios.get("/data/concerts");
const rawData = response.data;
const filteredData = rawData.filter((concert) => {
//let date = new Date(concert.datum);
// let newestDate = new Date("2022-09-29");
return concert.datum >= "2022-09-30";
});
setConcerts(filteredData);
};
loadConcerts();
}, []);
if (!concerts.length) {
return <p>Loading...</p>;
}
console.log(concerts); // getting full populated objects
return (
<div>
<h1>Newest concerts </h1>
<div>
<div className="card">
<img src={concerts.image} style={{ width: 100 }} />
<div className="card-text">
<div>
{concerts.map((concert) => {
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>);
})}
</div>
</div>
</div>
</div>
</div>
);
};
Change syntax of map function, either use return keyword with curly braces or just use round braces without return keyword. Eg
<div>
{concerts.map((concert) => {
return (
<React.Fragment>
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>)
</React.Fragment>
)
})}
</div>
Or
<div>
{concerts.map((concert) => (
<React.Fragment>
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>)
</React.Fragment>
))}
</div>
I have 3 files that make up a component. I am trying to calculate a bmi result which is split into several files. When I click calculate, the page changes. I have tried to find that I am new to React in general, and these are things that are probably easy but not yet obvious to me
import React, { useState } from "react";
import style from './BMI.module.css';
import Calculator from './Calculator'
import Result from './Result'
function BMI() {
const [page, setPage] = useState(0);
const checkPage = () => {
if (page === 0) {
return (
<button className={`${style.button}`}
disabled={page === 1}
onClick={() => {
setPage((currPage) => currPage + 1);
}}>Calculate</button>
)
} else {
return (
<button className={`${style.button}`} disabled={page === 0} onClick={() => {
setPage((currPage) => currPage - 1);
}}>Back</button>
)
}
}
const PageDisplay = () => {
if (page === 0) {
return <Calculator />;
} else {
return <Result />;
}
};
return (
<div className={`${style.wrapper}`}>
<div className={`${style.box}`}>
<div className={`${style.img}`}></div>
<div className={`${style.topSection}`}>
<h1 className={`${style.title}`}>{(page === 0 ? 'BMI Calculator' : 'Result')}</h1>
</div>
<div className="body">{PageDisplay()}</div>
<div>{checkPage()}</div>
</div>
</div>
)
}
export default BMI
import React, { useState } from "react";
import style from './Calculator.module.css'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faMars, faVenus } from '#fortawesome/free-solid-svg-icons';
const Input = ({ label, id, handleChange, name, type, placeholder }) => (
<>
<label className={`${style.label}`} htmlFor={id}>{label}</label>
<input className={`${style.input}`} type={type || "number"} id={id} name={name || id} placeholder={placeholder} onChange={(e) => handleChange(e.target.value)}></input>
<br />
</>
);
function Calculator() {
const [height, setHeight] = useState(0)
const [weight, setWeight] = useState(0)
const [age, setAge] = useState(0)
function removeSelected() {
const selectedBox = document.querySelectorAll('#head')
console.log(selectedBox.classList)
selectedBox.forEach(item => {
item.classList.remove(`${style.activeBox}`)
})
}
const handleToggle = (e) => {
if (!e.currentTarget.className.includes("activeBox")) {
removeSelected()
e.target.classList.add(`${style.activeBox}`)
} else {
e.target.classList.remove(`${style.activeBox}`)
}
};
return (
<>
<div className={`${style.content}`}>
<div className={`${style.middleSection}`}>
<h3 className={`${style.formTitle}`}>Choose your gender</h3>
<div className={`${style.genders}`}>
<div id="head" onClick={handleToggle} className={`${style.genderBox}`}>
<FontAwesomeIcon icon={faMars} className={`${style.genderIcon}`} />
<h3 className={`${style.genderBoxTitle}`}>Male</h3>
</div>
<div id="head" onClick={handleToggle} className={`${style.genderBox}`}>
<FontAwesomeIcon icon={faVenus} className={`${style.genderIcon}`} />
<h3 className={`${style.genderBoxTitle}`}>Female</h3>
</div>
</div>
</div>
<div className={`${style.bottomSection}`}>
<Input handleChange={setWeight} placeholder='Weight' label='Your weight (kg)'>{weight}</Input>
<Input handleChange={setHeight} placeholder='Height' label='Your height (cm)'>{height}</Input>
<Input handleChange={setAge} placeholder='Age' label='Your age'>{age}</Input>
</div>
</div>
</>
)
}
export default Calculator
import React, { useState } from 'react'
import style from './Result.module.css'
function Result() {
const [bmiScore, setBmiScore] = useState(0)
const [bmiDesc, setBmiDesc] = useState('')
return (
<div className={`${style.content}`}>
<div className={`${style.img}`}></div>
<div className={`${style.descriptions}`}>
<p className={`${style.bmiScoreDesc}`}>Your BMI is <span className={`${style.bmiScoreNumber}`}>{bmiScore}</span>, indication your weight is in the <span className={`${style.bmiScoreDesc}`}>{bmiDesc}</span> category for adults of your height</p>
<p className={`${style.descriptionBottom}`}>Maintaining a healthy weight may reduce the risk of chronic diseases associated with overweight and obesity.</p>
</div>
</div>
)
}
export default Result
So when i click Calculate which i have in the BMI.js take inputs value from Calculator.js calculate the score and put into paragraph in Result.js
What you will want to do in this case is at the top level, in BMI, that's where your bmiScore state variable should live. You can pass it to both toe Calculator (where it will be calculated) and the Result (where it will be displayed) via props, like so:
<Calculator bmi={bmiScore} /> and <Result bmi={bmiScore} />
Then the method signatures in each will look like:
function Calculator({ bmi }) and function Result({ bmi })
And you can use that bmi variable in both.
This is all because React passes variables down, not up. The only way to share across components is if a parent component holds the variable.
Sorry for my English is not very good. I'm learning React. I'm going to make a todo app. I want the 'input' content to appear as h4 when I press the button. But I can't map. Where do you think is the mistake?
import "./App.css";
import { useRef, useState } from "react";
function App() {
const [state, setState] = useState([]);
const inp = useRef(null);
const Add = () => {
setState([...state, inp.current.value]);
};
return (
<div className="App">
<input name="inp" ref={inp} />
<button onClick={Add}>Add</button>
{state.map((e) => {
<h4>{e}</h4>;
})}
</div>
);
}
export default App;
Change this
return (
<div className="App">
<input name="inp" ref={inp} />
<button onClick={Add}>Add</button>
{state.map((e) => {
<h4>{e}</h4>;
})}
</div>
);
into this
return (
<div className="App">
<input name="inp" ref={inp} />
<button onClick={Add}>Add</button>
{state.map((e) => {
return (
<h4>{e}</h4>;
)
})}
</div>
);
You forgot to return the element in map.
There are two ways of doing it.
// 1
array.map((el) => ( <div>{el}</div> ))
// 2
array.map((el) => { return <div>{el}</div> })
the problem is in inp.current.value you need to change it to
const Add = (evt) => {
var val = evt.target.value;
setState([...state, val]);
};
let me know if it work
I'm new to react.js and I want to apply the toggle feature at 'place-box' by using 'isOpen' state and my intention is it only works when I click single place-box div so I added onClick event at 'place-box' div. but all of the elements are toggled at the same time.
I guess it's because they all have the same class name.
how can I fix this?
import React, { useState, useEffect } from "react";
import { useQuery } from "#apollo/client";
import { FETCH_CITIES_QUERY } from "../../server/Data/RentQueries";
import PlaceResult from "../Rent/PlaceResult";
const CityResult = (props) => {
const [placeId, setPlaceId] = useState();
const [isOpen, setIsOpen] = useState(false);
const { loading, error, data } = useQuery(FETCH_CITIES_QUERY, {
variables: { cityName: cityName },
});
const showPlaceInfo = (placeId, e) => {
e.preventDefault();
setPlaceId(placeId);
setIsOpen((isOpen) => !isOpen);
};
return (
<div>
{data &&
data.cities.map((city) => {
return (
<div className="city-box">
{city.places.map((place) => {
return (
// this is place-box div and I added onClick event here
<div
className="place-box"
key={place.id}
onClick={(e) => {
e.stopPropagation();
showPlaceInfo(place.id, e);
}}
>
<li className="place-name">{place.name}</li>
{isOpen && (
<PlaceResult className="place-indiv" placeId={placeId} />
)}
{!isOpen && (
<div className="place-info-box">
<li>{place.address}</li>
{conditionCheck(city.condition)}
<li>{place.phone}</li>
</div>
)}
</div>
);
})}
</div>
);
})}
</div>
);
};
export default CityResult;
Your variable isOpen is used for all cities. If you change isOpen to true all place-boxes are opened. You should store the id of the currently opened city inside a variable and compare against it to check if the current city in the for loop should be opened.
import React, { useState, useEffect } from "react";
import { useQuery } from "#apollo/client";
import { FETCH_CITIES_QUERY } from "../../server/Data/RentQueries";
import PlaceResult from "../Rent/PlaceResult";
const CityResult = (props) => {
const [placeId, setPlaceId] = useState();
const [openedPlaceId, setOpenedPlaceId] = useState(undefined);
const { loading, error, data } = useQuery(FETCH_CITIES_QUERY, {
variables: { cityName: cityName },
});
const showPlaceInfo = (placeId, e) => {
e.preventDefault();
setPlaceId(placeId);
setOpenedPlaceId(placeId);
};
return (
<div>
{data &&
data.cities.map((city) => {
return (
<div className="city-box">
{city.places.map((place) => {
return (
// this is place-box div and I added onClick event here
<div
className="place-box"
key={place.id}
onClick={(e) => {
e.stopPropagation();
showPlaceInfo(place.id, e);
}}
>
<li className="place-name">{place.name}</li>
{openedPlaceId === place.id && (
<PlaceResult className="place-indiv" placeId={placeId} />
)}
{!(openedPlaceId === place.id) && (
<div className="place-info-box">
<li>{place.address}</li>
{conditionCheck(city.condition)}
<li>{place.phone}</li>
</div>
)}
</div>
);
})}
</div>
);
})}
</div>
);
};
export default CityResult;
This way only the clicked place will be opened.
I'm trying to build a TicTacToe application.
Problem occured when I tried to convert from class to func. components.
I'm familiar with setting the state variable and the function to change the state of the variable, but passing into the return... i get confused.
import React from "react";
class Endgame extends React.Component {
state = {
tied: "You guys tied",
playerWin: "You win " + this.props.winner + " !!",
};
handleClick = () => {
this.props.endgame(false);
};
render() {
const { winner } = this.props;
const { tied, playerWin } = this.state;
return (
<div className="wrapper">
<div className="screen">
<p>{winner === "Tied" ? tied : playerWin}</p>
<button className="btn-primary" onClick={this.handleClick}>
Start again?
</button>
</div>
</div>
);
}
}
export default Endgame;
import React, { useState } from "react";
const Endgame=({winner,endgame})=>{
const [state,setState]=useState({
tied: "You guys tied",
playerWin: `You win ${winner} !!`,
})
const handleClick = () => {
endgame(false);
};
return (
<div className="wrapper">
<div className="screen">
<p>{winner === "Tied" ? state.tied : state.playerWin}</p>
<button className="btn-primary" onClick={handleClick}>
Start again?
</button>
</div>
</div>
);
}
export default Endgame;
here it is converted into functional component
You can easly transform this component in function component in this way:
import React, { useState } from "react";
const Endgame = ({ winner, endgame }) => {
const [tied, setTied] = useState("You guys tied");
const [playerWin, setPlayerWin] = useState("You win " + winner + " !!");
const handleClick = (e) => {
endgame(false);
};
return (
<div className="wrapper">
<div className="screen">
<p>{winner === "Tied" ? tied : playerWin}</p>
<button className="btn-primary" onClick={handleClick}>
Start again?
</button>
</div>
</div>
);
}
export default Endgame;
This is an intersting article that explains step by step how to convert component to funcional component.