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

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?

Related

React change ClassName based on data [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 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>
);

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
/>

How to change checkbox in react correctly? [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 3 years ago.
Improve this question
What is the correct way to change checkbox value?
option 1
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [x, setX] = useState(false);
const soldCheckbox = ({ target: { checked } }) => {
console.log(x, checked);
setX(checked);
};
return (
<div>
<input type="checkbox" checked={x} onChange={soldCheckbox} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
option 2
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [x, setX] = useState(false);
console.log(x);
return (
<div>
<input type="checkbox" checked={x} onChange={() => setX(!x)} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
In fact, I think there's no difference, but I just wanted to hear a different opinion. Maybe something I do not know or there may be other solutions to this problem.
Both ways are almost the same, but the first option actually is more redundant, let's analyze why:
Both the first and second methods are implementing controlled components
This means that you are providing a value and a way to change it, so the responsibility to update and control the values are abstracted from the component.
But why the first way is redundant?
You don't actually need to read from the e.target.checked cause it always reflects the local state x, so there is no need to read from e.target.checked and reverse it by doing: setX(!e.target.checked) since x and the e.target.checked will always be the same.
Caveats
Even though is fine to do onClick={e => parentHandler(e)} in a inline expression(arrow function) you should be careful, passing it like this to an input won't cause any problems, but when you are passing to a child component that implements React.memo or PureComponent for example, this will actually re render the component everytime, cause a new instance of the function is always created (signature is the same, but the shallow comparison will always return false cause they are different instances), so for optimization reasons is always best pass props like this: <Child onClick={this.clickHandler} id={item.id} /> and on the child: onClick={() => this.props.onClick(this.props.id)} instead of just: <Child onClick={e => this.onClick(item.id)} />
In this specific case, I would have chosen option 2, cleaner code in my opinion.
setX changes the state, no need for a function calling setX and extracting the value from event if we know the value is x.
I think that it all depends on the situation.
The first option will be better if you have a lot of form and components. You can handle all with one handler.
const handler = (e) => {
const { target } = e;
const value = target.type === 'checkbox' ? target.checked : target.value;
const { name } = target;
setForm( f => ({ ...f, [name]: value }));
};
Second, if checkbox is one and the application must somehow react to its change.
there is a third way to uncontrolled inputs.
The only difference is clean coding, first way is better if you need to do something except changing state (for example to call an http request) and the second is good if you just need checkbox to work and store its value.
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [x, setX] = useState(false);
const soldCheckbox = ({ target: { checked } }) => {
console.log(x, checked);
setX(checked);
};
return (
<div>
<input type="checkbox" checked={x} onChange={soldCheckbox} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I'm always choosing option 1 because it is a way more generic way for defining form field change events. In most of the cases, I have something in generic form components
function SomeForm() {
const [formData, setFormData] = useState({ name: "", accept: false });
const onFieldChange = ({ target: { name, value, checked } }) => {
if (typeof checked !== 'undefined') { // checking if we have a "checked" field inside target
setFormData({ [name]: checked });
}
setFormData({ [name]: value });
}
return (
<form>
<input type="text" name="name" value={formData.name} onChange={onFieldChange} />
<input type="checkbox" name="accept" checked={formData.accept} onChange={onFieldChange} />
</form>
)
}
The idea behind this is that any way we are going to receive a target DOM object which contains both checked and value, so we can make it generic.
Hope this helps
It looks like both of your options are equivalent. If we look at the documentation for the onChange event provided by React (not the change event provided by html) it states:
The onChange event behaves as you would expect it to: whenever a form field is changed, this event is fired.
We intentionally do not use the existing browser behavior because onChange is a misnomer for its behavior and React relies on this event to handle user input in real time.
DOM Elements
So, simply choose the option that you think produces cleaner code.

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

How to delete state in every Reducer with single action [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have 10 reducer and I want to delete state values in every reducer with
a single click, how can I achieve this?
I think the most straight forward way to reset history would be to create an action that the 10 reducers listen for and when it occurs they reset their state accordingly. Here is an example:
class ResetState extends Action {
readonly type = "RESET_STATE"
}
reducer 1
function reducer1(state, action){
switch(action.type) {
case "RESET_STATE":
return {};
}
}
reducer 2
function reducer2(state, action){
switch(action.type) {
case "RESET_STATE":
return {
someCount: 0,
someArray: [],
someBoolean: false,
};
}
}
You can create a metaReducer like so.
export function clearData(reducer: ActionReducer<any>): ActionReducer<any> {
return function (state, action) {
switch (action.type) {
case CLEAR_DATA:
state = undefined;
}
return reducer(state, action);
};
}
and include it in your metaReducers array which will be finally fed to StoreModule initialisation in your feature modules.

Categories

Resources