React change ClassName based on data [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
I have this code which goes and get the data from API,
const getDevices = async () => {
const response = await fetch(`${API_URL}`);
const json = await response.json();
setData(json);
for (let i in json) {
Object.values(json[i].portOn.split(",")).forEach((value) => {
if (value === "G01") {
blinkStatus = "blink_me";
}
}
and also I have this in return which is supposed to change the className:
<div id="portG01" className={blinkStatus}></div>
But it doesn't work. the DIV doesn't get the className. No error at all.
I am trying to read the data from database and then change the className according to the data.
This is what I need as result:
<div id="portG01" className="blinkStatus"></div>

You need to have blinkStatus changing trigger a rerender of the component. To do this, you can use state. So you can do:
import React, { useEffect, useState } from "react";
...
const [blinkStatus, setBlinkStatus] = useState();
// useEffect(() => {}, []) is the equivalent of the old componentDidMount
useEffect(() => {
const value = await ... // get blink status
setBlinkStatus(value);
}, []);
...
return (
<div className={blinkStatus}>
...
</div>
);

Related

React components with common handler for update and create [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 days ago.
Improve this question
I'm trying to find the best way to create and update items in a list. So, I have a form with item fields and I have the idea to provide a function (update or create) depending on the mode I choose. For example, I click the edit button and set the "update" mode, or I click the "add new item" button and set the "create" mode. In this case I don't need to add two identical components with different click handlers (one for update, one for create), I will just provide a click handler depending on the mode state.
What do you think about this implementation?
import {useState} from "react";
enum MODES {
view= "view",
update= "update",
create= "create",
}
const Page = () => {
const [mode, setMode] = useState<MODES>(MODES.view);
const [clickHandler, setClickHandler] = useState<() => void>();
const [item, setItem] = useState({});
const updateHandler = () => {};
const createHandler = () => {};
const setModeHandler = (mode: MODES) => {
switch (mode) {
case MODES.update: {
setItem(selectedItem);
setClickHandler(updateHandler);
} break;
case MODES.create: {
setItem({});
setClickHandler(createHandler);
} break;
default: {
} break;
}
}
return (
<div>
<div>
<button onClick={() => {setModeHandler(MODES.update)}}>update</button>
<button onClick={() => {setModeHandler(MODES.create)}}>create</button>
</div>
<ItemModal click={clickHandler} item={item} />
</div>
)
}
I attached the draft to better understand my question.
I would be glad to hear your opinion on this matter.
What do you think about this idea?
Is it okay or better to use to components with different handlers?

Creating dynamic buttons

Trying to create a small app as part of a university assignment using React.
The basic assignment is to create a page which has a question and then has one of 5 answers. I have the answers now stored in a firestore document.
I have created (the start of) a custom Button component.
So the code I have does contact the firestore and I get the data back. The examples I have tried in uni have been for getting 1 bit of data - not like this. What I'm trying to do is to create an answers "array" which I can then iterate over and create my custom buttons. However, I can't quit figure out how to create the array of answers.
Can anyone give me a hint?
import React, {useEffect, useState} from 'react';
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import 'firebase/compat/storage';
import Button from '../components/Button';
function AnswerComponent() {
const firestore = firebase.firestore();
//const storage = firebase.storage();
const collectionId = "Balances";
const documentId = "Answers"
const [answers, setAnwsers] = useState([]);
useEffect(() => {
const getFirebase = async () => {
const snapshot = await firestore.collection(collectionId).doc(documentId).get();
const questionData = snapshot.data();
// now we add the answers and correct flag to our answers
const answerArr = [];
Object.keys(questionData).forEach(key => {
answerArr.push(questionData[key]);
setAnwsers(answerArr)
});
};
getFirebase();
},[answers, firestore])
console.log(">>", answers)
return (
<div className="col-12">
<h3 className="text-center">Answer</h3>
<div className="p-3 mb-2 bg-light">
<div className="row">
</div>
{/* {btns} */}
</div>
</div>
)
}
export default AnswerComponent;
Need to push new answers onto the array, this solution saves each answer as an object with a key (preserving the key).
const answerArr = [];
Object.keys(questionData).forEach(key => {
answerArr.push({ [key]: questionData[key] });
setAnswers(newAnswerArr);
});
If you don't need the key you could save a step and use Object.values:
const answerArr = [];
Object.values(questionData).forEach(questionValue => {
answerArr.push(questionValue);
});
setAnwsers(answerArr);
Or with either solution you could reduce instead of setting the anwserArr separately:
const answerArr = Object.values(questionData).reduce((acc, questionValue) => {
acc.push(questionValue)
return acc;
}, []);
setAnswers(answerArr)
It looks like you're trying to setAnswer several times in a row (which will change the answer) when you do this:
Object.keys(questionData).forEach(key => {
console.log(key, questionData[key]);
setAnwsers(key, questionData[key])
});
Instead, I would try to create a singe array, then setAnswers to that array
const answerArray = []
Object.keys(questionData).forEach(key => {
console.log(key, questionData[key]);
answerArray.push(questionData[key]);
});
setAnswers(answerArray)
Turns out either piece code works (thanks to both #chris-bradshaw and #radicalturnip. The issue was I forgot useEffect changes on every change. So useEffect was triggered, getting data, that was triggering a change, which ran useEffect, which got more data and triggered another change, etc etc x infinitity.

UseState to control [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I use a button to control the audio player mute but it makes the player default mute, I want that only mute when clicking.How to edit it
import React, { useState } from "react";
import ReactAudioPlayer from "react-audio-player";
const Test = () => {
const [ismute, setOpen] = useState(false);
return (
<><div>
<ReactAudioPlayer
controls
muted={ismute ? "false": "True"}
src='https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
loop
autoPlay
/>
</div><button onClick={() => setOpen(!ismute)}>click me!</button>
</>
);
};
export default Test
If you are passing as string,
muted={ismute ? "false": "True"}
since the initial value of the ismute is false as:
const [ismute, setMute] = useState(false);
then what you are going to pass as a prop is True or false which is truthy value which makes ismute as always mute
For state ismute, initially assign value true instead of false as below:
const [ismute, setOpen] = useState(true);
You should pass muted prop as either true or false. You are passing as a string
muted={ismute ? false: true }
I've created a simulation for player
For state ismute, initially assign value true instead of false as below:
const [ismute, setOpen] = useState(true);
Another correction might be at component ReactAudioPlayer:
<ReactAudioPlayer
controls
muted={ismute}
src='https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
loop
autoPlay
/>

React "Uncaught TypeError: undefined has no properties" [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm currently learning stuff in JavaScript and React and I face a problem I don't understand. For some reasons the code won't compile and I get this error. I think the problem is when I call the "getFact" function but I don't understand why !
I get this error : Uncaught TypeError: undefined has no properties
Here's my code :
const App = () => {
useEffect(() => {getFact();}, []);
const apiLink = "https://api.chucknorris.io/jokes/random";
const [value, setValue] = useState('nothing');
const getFact = async () => {
const data = await fetch(apiLink);
const dataJson = await data.json();
setValue(dataJson.value);
}
return (
<div className="App">
<h1 onClick={this.getFact}>New Fact</h1>
</div>
);
}
I hope you'll be able to help me !
Thanks
EDIT
I now know wasn't supposed to use "this" but may I ask why I've seen some examples where "this" is used and everything works fine ? for example :
handleClick() {
this.setState(state => ({isToggleOn: !state.isToggleOn}));}
render() {
return (
<button onClick={this.handleClick}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>
);
}
You're using a functional component, where this is non-existent. You just need to change to getFact and it should work. Here's a working code:
const App = () => {
useEffect(() => {getFact();}, []);
const apiLink = "https://api.chucknorris.io/jokes/random";
const [value, setValue] = useState('nothing');
const getFact = async () => {
const data = await fetch(apiLink);
const dataJson = await data.json();
setValue(dataJson.value);
}
return (
<div className="App">
<h1 onClick={getFact}>New Fact</h1>
</div>
);
}

How Can I consume this Json using React-Native? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
i'd like to know how can I use and consume this json, showing and updading always the list, please i need this for my work and i am struggling to make it.
HERE THE JSON
It's just like in React. First you should fetch the data(usually componentDidMount() is a good place for that. You need to update your component's state to contain the fetched data. Here is an example using axios, but the same effect can be achieved with fetch API.
class MyComponent extends Component {
state = {
data : []
}
componentDidMount(){
axios.get('myendpoint')
.then(res => this.setState({data : res}))
}
render(){
const { data } = this.state
return(
<FlatList
data={data}
renderItem={({item}) => <Text>{item}</Text>}
/>
)
}
}
With fetch
class MyComponentWithFetch extends Component {
state = {
data : []
}
componentDidMount(){
fetch('myendpoint')
.then(docs => docs.json())
.then(res => this.setState({data : res}))
}
render(){
const { data } = this.state
return(
<FlatList
data={data}
renderItem={({item}) => <Text>{item}</Text>}
/>
)
}
}
ps: Don't forget the keys

Categories

Resources