React and accepted standards - reactjs

Perhaps not the best place to ask this question. If not, please point me down the trail I need to go.
I've started working with ReactJS to freshen up programming vernacular and I believe I have the hang of the principle concepts; however, while learning a new programming language I have found MANY MANY different ways to do things (such as the case with computer programming). I have a simple input component I want to use in my design:
class TextField extends Component{
constructor(props,context){
super(props,context);
this.state = {errmsg: ''}
this.setError = this.setError.bind(this);
}
setError(errormessage){
this.setState({
errmsg: errormessage
})
}
render(){
var inpdiv = this.props.id + "_div";
var errdiv = this.props.id + "_err";
return(
<div id={inpdiv}>
<label for={this.props.id}>{this.props.label}
<input type="text" id={this.props.id} name={this.props.id} />
<div id={errdiv}>{this.state.errmsg}</div>
</label>
</div>
)
}
}
export default TextFieldest;
Notice the setError function. I call this function from another (parent) component:
class Form extends Component{
constructor(props,context){
super(props,context)
this.emailaddress_ref = React.createRef();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(){
this.emailaddress_ref.current.setError('Testing the Error Area of the Test Component');
}
render(){
return(
<div>
<Test id="emailaddress" ref={this.emailaddress_ref} label="Enter Email Address" />
<Button btntext="Press Me!" handleclick={this.handleSubmit} />
</div>
)
}
}
export default Form;
My question is:
Is this the most accepted way to handle changing the state of a child component or am I going down a bad path here?

You might rather want to pass down the error function via props, since it decouples one component from another, and it doesnt lead to a point where if you render two or more components you will have a mess handling refs in secenarios where you really dont need them. refs are rare in their need, and while you can bend them your way, its much saner to just send things via props. In general using ids for reusable components either is not a great idea.
You will need to realize in your case for example who should handle the error and to what extent. Is you text input semi autonomous with regards to input validation? If you reuse is elsewhere will you believe that its validation should be handled by parent? Both yes and no are valid answers, but you need to understand who owns the flow in your app.

Related

How to update a child component that extends a parent class when the parent class updates?

I have a page that has a number of forms on it. In an effort to try and keep the forms consistent, I have a main Form class component that is extended by all the other forms.
This parent Form component has the logic in it to add field validation, along with adding secure tokens before and after the form fields:
Parent Form
class Form extends React.Component {
constructor(props) {
super(props);
}
view(child) {
return (
<>
<form onSubmit={this.handleSubmit} className="form">
... // extra form fields
{child} // 'actual' form fields, passed from child
... // extra wrapper form fields
<button>Submit</button>
</form>
</>
);
}
}
export default Form;
Child Form
class LoginForm extends Form {
constructor(props) {
super(props);
this.state = {
data: {} ... form-field specific data
}
}
render() {
return this.view(
<>
<MyFormField name="field1" onChange={this.handleChange} onBlur={this.handleBlur} field={this.state.data.field1} />
<MyFormField name="field2" onChange={this.handleChange} onBlur={this.handleBlur} field={this.state.data.field2} />
<MyFormField name="field3" onChange={this.handleChange} onBlur={this.handleBlur} field={this.state.data.field3} />
</>
);
}
}
export default LoginForm;
The LoginForm (child) extends the parent Form, and in its render method, calls the view method of the parent. This effectively will render the pieces passed over with the parent handling validation and such.
The problem it is facing, is that when an update is performed on one of the fields, it is not updating the child (LoginForm) - so any field validation errors are not displaying, and so forth.
Page
class MyPageComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<>
<div className="my-page">
<h2>header</h2>
<LoginForm /> // including LoginForm
</div>
</>
);
}
export default MyPageComponent;
The MyPageComponent will create the layout, and then embed the form in the page wherever it may be. The embedded form, in this case - LoginForm will contain all the handlers for the validation, submission, state and all that of the form.
Is this an anti-pattern? I have not found anything so far to suggest so, but it is frustrating - and I cannot help but wonder if there is a better way to do this. The only part that strikes me as somewhat unconventional, is that the child's render method calls the parent classes view method.
My goal in all this is just to create a consistent handler for all the forms on the site that can easily be reused.
How do I get the child/LoginForm to update when it is updated in the parent Form? Is there a better way to do this?
Edit
Updates to the state.data.field elements are the updates that I am referring to. These are updated by running this.setState(newState) on the Form component. Usually, a state change would trigger a render update?

Where should I create references for DOM elements in Reactjs?

class SearchInput extends React.Component {
constructor(props) {
super(props);
this.searchInputRef = React.createRef(); // 👈️ LOOK HERE
}
onFormSubmit = (e) => {
e.preventDefault();
// const query = e.target.querySelector("#searchInput").value; // 👈️ LOOK HERE
const query = this.searchInputRef.current.value;
console.log(query);
};
render() {
return (
<form onSubmit={this.onFormSubmit}>
<div className="input-group-text">
{this.props.label}
<input
type="text"
className="form-control"
id="searchInput"
aria-describedby="emailHelp"
placeholder="Search"
ref={this.searchInputRef}
/>
<button type="submit" className="btn btn-primary">
<i className="fas fa-search"></i>
</button>
</div>
</form>
);
}
}
I'm very new to ReactJS, but I'm having hard times with it, I have two questions about my component above:
on the first // 👈️ LOOK HERE comment above, you see, I'm saving the references to the class instance itself (in the constructor) which leads to two downsides:
The constructor will become very messy later when I add 7 or 8 references inside of it, which makes it non-clean code.
We're saving the reference to the object body of the class instance, do you think this is a clean-code? maybe there should be something in React that allows me to store all the references inside one property may be called "refs", so the instance of that class would look like the following:
{
refs: {
searchInputRef: ...
// later
buttonRef: ...
button2Ref: ...
iconRef: ...
}
state: ...
// the rest of the component object
}
Which is more cleaner if you ask me.
If I'm wrong, please let me know.
on the second comment // 👈️ LOOK HERE of course you can see I don't actually need a reference in my case, so why I'm using ref sys~? I can simply get the input from e.target.querySelector("#searchInput") as simple as it looks like, why folks are always saying it's a shame and a bad practice to use my beloved querySelector to reference DOM elements when using React?
Well, I think the people you mentioned (those who say using DOM is embarrassing) are completely wrong!
They have probably never read the official ReactJs documents and are merely expressing their personal (and completely wrong) opinion.
Stop Overuse Refs!
According to the documentation on the ReactJs website, overuse of the Refs is completely wrong. ReactJs recommends that you do not even use open() or close() modals.
So the best option we can choose is to use DOM.
But this does not mean that ReactJs has put a useless thing in its library facilities. Not at all.
So when to Use Refs?
There are some great cases where using Refs is very economical. For example, to focus on fields or create multiple animations.
In my opinion, there is nothing that Refs can not do. And on the other hand, there is nothing that can not be done with DOM. Both are fully functional.
What matters is the performance and efficiency of each.
DOM is a proven thing in the web world, but according to ReactJs, overuse of Refs can be harmful.
Anyway, this is a general overview of Refs and DOM that I would like to share with you.
I hope other people give you suggestions on how to use Refs better.
Finally, there is another important issue.
I understand from your question that you care a lot about the performance of your program. But I was wondering why you do not use functional components instead of class components?
Using functional components can greatly enhance the performance, efficiency and speed of your program. I hope you read about it and improve the performance of your program by migrating to functionals.
Please Read This Articles:
Components and Props
Introducing Hooks
React Function Components
At first // 👈️ LOOK HERE,
You could have a function to create ref, to distinct them i prefer an id.
class SearchInput extends React.Component {
constructor(props) {
super(props);
}
refs = {} // 👈️ LOOK HERE
getRef(id) { // 👈️ LOOK HERE
if (!this.refs.hasOwnProperty(id)) {
this.refs[id] = React.createRef();
}
return this.refs[id];
}
render() {
const
return (
<form onSubmit={this.onFormSubmit}>
<div className="input-group-text">
{this.props.label}
<input
type="text"
className="form-control"
id="searchInput"
aria-describedby="emailHelp"
placeholder="Search"
ref={this.getRef(id)} // 👈️ LOOK HERE, id - you decide
/>
<button type="submit" className="btn btn-primary">
<i className="fas fa-search"></i>
</button>
</div>
</form>
);
}
}
At second // 👈️ LOOK HERE, i think this question has been asked you should do a search for it.

What is this Component and how does it differ from others

I'm self-teaching React and was just wondering if someone could clear something up for me.
I have this component, which seems to be doing everything I need it to:
const Projects = ({ projectData }) => {
const { url } = useRouteMatch();
return (
{projectData.map((project) => (
<div className="project-container" key={project.id}>
<div className="project-image">
</div>
<div>
<h2>{project.name}</h2>
<p>{project.description}</p>
<div>
<Button class="button link_right relative" linkTo={`${url}/${project.id}`} btnText="Explore" />
</div>
</div>
</div>
))}
);
};
export default Projects;
While watching tutorials and reading documentation I'll typically see Function and Class Components but not whatever this is:
const ComponentName = () => {
So, my questions are:
What sort of component is my example known as
What purpose does it
serve when compared to a Function Component or a Class Component,
How would a Function Component or a Class Component need to look in
order to do everything that my example component is currently doing.
Thanks!
Making instance of class is too slow, because of calling constructor and inheritance. Functional components are just functions, there are no such overheads.
In addition, there is how to treat this. In class, entity of this is often unclear and that confused us. Arrow function reduce it, but using class, we must use this. this caused complicated management of state too. And class object has state itself, so it was troublesome.
Function, defined carefully, is easy to keep purity. It has no state itself. It means that state management is not bother us. Data flow is cleared.

Handling form submissions without handling changes?

I'm new to front-end development so please forgive me if this is an ignorant question. I'm using ReactJS to build a simple SPA with several form components. In the official React docs and other tutorials I've read online, it seems like to be able to handle a form submission, I also have to handle form changes, i.e. update the component state with each keystroke, like so:
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
This seems wasteful to me since I'm only interested in the final form value that's been submitted. Is there a way to access the value of the submitted form in the submission event handler so that I can only update the state once and eliminate the need to handle any non-submission change?
It may seem wasteful, but that is exactly the React way of doing it:
https://reactjs.org/docs/forms.html
Any way of trying to get around this would be more hacky than efficient. This may help keep you from duplicating code while trying to track all your input values:
When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name.
This way you only need one 'handleChange' method.
A controlled component is not really necessary in this case. Update the input component to:
<input type="text" name="username" required/>
Now handle only the onSubmit. The value can be retrieved at:
event.target.username.value
Add the attribute "required" to the input tag for automatic validation.

Joining React flux with redux

Is it good solution to join (interact) Redux with flux in one project like below?
The state (inputText) is in our component (TOdoInput), not in store as it should be in Redux. Is it correct to have local state in Redux?
class TodoInput extends Component {
constructor(props, context) {
super(props, context)
this.state = {
inputText: ''
}
}
handleChange(event) {
this.setState({
inputText: event.target.value
})
}
handleSubmit(event) {
event.preventDefault()
this.props.addTodo(this.state.inputText)
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit.bind(this)}>
<input
type="text"
placeholder="Type in your todo"
value={this.state.inputText}
onChange={this.handleChange.bind(this)}
/>
<input type="submit" value="Submit"/>
</form>
</div>
)
}
Yes it is correct.
Local (component state) vs Global state (reducer) is a matter of concern.
For example take a tabs bar component which displays user informations
A tabs bar should know which tabs is active. No other component cares about so it could be a local component state handled with this.state.
On the other hand the user information of the tab is a global concern. Indeed, a lot of your components app should be interested to display name, age, etc. So this state should be stored in a reducer.
The main role of your TodoInput is to prepare the text to be send to the reducer. So input value is only important during the time the user is typing.
you can format the text
you can ask to a service is there is a typo
...
Once you are sure the text is OK with the concern of you app, you validate it. At this step, the concern of you value changes. It is now a value which could be consumed by other components. So it must be stored in a global store (the redux reducer).

Resources