hooks are not rendering in react - reactjs

In react, I am trying to use react hooks.I have created one hook which contains a form and I am importing that in class based component and rendering it there. But hooks is not rendering in contact component
//contactushook.js
import React from 'react';
const contactUshook = props => {
return <React.Fragment>
<form>
<div>
<input id="name" type="text" placeholder="enter the name"></input>
</div>
<div>
<input id="email" type="email" placeholder="enter the email"></input>
</div>
<div>
<input id="message" type="text-area" placeholder="Type message here"></input>
</div>
<button type="submit">Submit</button>
</form>
</React.Fragment>
}
export default contactUshook;
//contact.js
import React, { Component } from 'react';
import contactUshook from './hooks/contactushook';
class ContactComponent extends Component {
render() {
return (
<div>
<h4>hook</h4>
<contactUshook></contactUshook>
</div>
);
}
}
export default ContactComponent;

Your code is pretty working. You've should name your custom component <contactUshook> starting with capital letter, so React knows that it is custom component and not html tag.
Note: Always start component names with a capital letter.
React treats components starting with lowercase letters as DOM tags. For example, represents an HTML div tag, but represents a component and requires Welcome to be in scope.
So this will fix you issue
import React, { Component } from 'react';
import ContactUshook from './hooks/contactushook';
class ContactComponent extends Component {
render() {
return (
<div>
<h4>hook</h4>
<ContactUshook></ContactUshook>
</div>
);
}
}
export default ContactComponent;
And as already mentioned, your code does not deal with hooks. You created ordinary components.
Working sample is here

Related

React class component is not rendering scss on website

I was changing functional components to class components and I ran up
to a problem. My scss was gone after updating the code. Before
refactoring my functional component into class component everything
was working fine in scss but then it's just like I haven't even
imported styles.scss file in my index.js. But as you can see it is
imported.
import React, {Component}from 'react';
import './styles.scss';
class FormInput extends Component {
constructor(handleChange, label, ...otherProps) {
super(handleChange, label, ...otherProps);
}
render(){
return (
<div className="formRow">
{this.label && (
<label>
{this.label}
</label>
)}
<input className="formInput" onChange={this.handleChange} otherProps />
</div>
);
} };
export default FormInput;

Squaring the value of an input box in React

I am new to learning React and doing a little test project each day. Today, I am trying to create an input box that when I click a Submit button, it alerts the square of a number. Nice and simple. But, I am trying to do this without using State. Just trying to understand how. Here is my code but something is missing. I think I am close!
Any ideas?
import { render } from '#testing-library/react';
import React from 'react';
class App extends React.Component {
sayHi = props => {
alert(this.props.mySentProps);
};
squareTheNumber = () => {
alert('this is the squared number'+ );
};
render() {
return (
<div>
<div onClick={this.sayHi}>
<h1>Hello World</h1>
</div>
<div>
<input type="text" placeholder={'Enter a number to square'} />
</div>
<div>
<button onClick={this.squareTheNumber}>Submit me</button>
</div>
</div>
);
}
}
export default App;
Try this:
import React from "react";
import "./styles.css";
class App extends React.Component {
sayHi = (props) => {
alert(this.props.mySentProps);
};
squareTheNumber = (event) => {
event.preventDefault();
// Should be the same as input's "name" or "id" property
// Docs: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
const { number } = event.target.elements;
alert(`this is the squared number: ${number.value ** 2}`);
};
render() {
return (
<div>
<div onClick={this.sayHi}>
<h1>Hello World</h1>
</div>
<div>
<form onSubmit={this.squareTheNumber}>
<input
name="number"
type="text"
placeholder="Enter a number to square"
/>
<button type="submit">Submit me</button>
</form>
</div>
<div></div>
</div>
);
}
}
export default App;
P.S.: render from #testing-library/react is used for testing purposes only. See docs here. Class components have their own field with the same name.
As said, there is no clean way to do it without state or any extensions. The best way is to use state and make things clean. But another way you can do it is to use JQuery.
For example:
You can assign the <input> an id, say myId. Then you do this:
var content = $('#myId').content;
And then you can change the content in the p by assigning it a new value.
But using JQuery kinds of defeats the purpose of React, so I would recommend using state.
You can use refs to access mounted elements directly.
https://reactjs.org/docs/refs-and-the-dom.html

Material Components Web and React: Cannot read property 'querySelector' of undefined;

I am trying to build a Modal component taking advantage of React and Material Components Web. The visibility of Modal is inherited from the parent state as props:
import React, {Component} from 'react';
import {MDCFormField} from '#material/form-field/';
import {MDCTextfield} from '#material/textfield/';
import './modal.scss';
export default class Modal extends Component {
componentDidMount() {
this.email = new MDCTextfield(this.email);
this.pwd = new MDCTextfield(this.pwd);
}
componentWillUnmount() {
this.email.destroy();
this.pwd.destroy();
}
render() {
if (this.props.isModalOpen){
return (
<div id="modal-container">
<div id="mask"></div>
<div id="modal">
<form className="mdc-form-field">
<div ref={(div) => {this.email = div}} className="mdc-textfield">
<label type="email" htmlFor="email" className="mdc-textfield__label">Your email</label>
<input type="text" id="email" className="mdc-textfield__input"/>
<div className="mdc-textfield__bottom-line"></div>
</div>
<div ref={(div) => {this.pwd = div}} className="mdc-textfield">
<label htmlFor="pw" className="mdc-textfield__label">Password</label>
<input type="password" id="pw" className="mdc-textfield__input" required minLength={8}/>
<div className="mdc-textfield__bottom-line"></div>
</div>
</form>
</div>
</div>
);
} else {
return null
}
}
}
As soon as the app initialise an error appears "TypeError: Cannot read property 'querySelector' of undefined”
Of course it does since the since as the Modal is returning null.
so i tried to initialise Material Components as
componentDidMount() {
this.email = this.email && new MDCTextfield(this.email);
this.pwd = this.pwd && new MDCTextfield(this.pwd);
}
In this case the error is not thrown anymore but obviously the components are not initialised.
I did not come up with a pattern to solve this problem. Also a css approach did not work ( the idea was to toggle .someClass {display: none} from the main container ).
/** SOLVED **/
Ok I came up with a working pattern to solve the problem.
The problem was in the architecture of the app and the encapsulation of the components was not appropriate.
This is a parent component called Modal:
import React, {Component} from 'react';
import EmailField from './email-field';
import PwdField from './password-field';
import './modal.scss';
export default class Modal extends Component {
render() {
if (this.props.isModalOpen){
return (
<div id="modal-container">
<div id="mask"></div>
<div id="modal">
<form className="mdc-form-field">
<EmailField />
<PwdField />
</form>
</div>
</div>
);
} else {
return null
}
}
}
Than we have Children components as
import React, {Component} from 'react'
import {MDCTextfield} from '#material/textfield/';
export default class EmailField extends Component {
componentDidMount(){
this.email = new MDCTextfield(this.email);
}
componentWillUnmount(){
this.email.destroy();
}
render(){
return(
<div ref={(div) => {this.email = div}} className="mdc-textfield">
<label type="email" htmlFor="email" className="mdc-textfield__label">Your email</label>
<input type="text" id="email" className="mdc-textfield__input"/>
<div className="mdc-textfield__bottom-line"></div>
</div>
);
}
}
I was trying to init and destroy from a different scope of MDCTextfield elements.
You should try out the react version of this library.
Try to console.log(this.email). Afterwards you will see, that ref that you try to pass is not a selector, this is expected when you initialise matertial-components.
#Fawaz answer is correct, but you can instantiate it the way you want, even on div.
Showcase: https://www.webpackbin.com/bins/-KwEsyJR3O3eW50gX2pq
Did you using components like i am using there?
Use this for reference:
Material Components Textfield, Manual Instantiation

Reactjs: how to put the html template in a separate file?

I'm new to React. I'm much more familiar with Angular2+. In Angular, every component has a separate html file. However, in React, I see that render function itself includes the html template. For example,
import React, { Component } from 'react';
class HelloWorld extends Component {
render() {
return (
<h2> Hello World </h2>
);
}
}
export default HelloWorld;
Well I want to take
<h2> Hello World </h2>
outside the js file and put it in a separate html and import the html file to render function, for example
render() {
return (
import content of helloworld.html
);
}
Do you know how to do it?
In React you would typically make a child component and import it into the parent component.
Since your child component here would just be static markup i.e <h2>Hello World</h2>, you don't need to worry about component state.
Therefore, you could do the following:
make a functional (aka stateless or dumb) component for your text. You could name it HelloWorldText as an example.
import this functional component into your parent component HelloWorld.
Your functional component would look something like this:
HelloWorldText.js
const HelloWorldText = () => ( <h2> Hello World </h2> );
export default HelloWorldText;
Then you would import this functional component HelloWorldText into your parent component HelloWorld like so:
HelloWorld.js
import React, { Component } from 'react';
import HelloWorldText from './path/to/HelloWorldText';
class HelloWorld extends Component {
render() {
return (
<HelloWorldText />
);
}
}
export default HelloWorld;
Here's a CodePen Demo with this code.
Unfortunately on CodePen you can't export and import components, but hopefully it still gives you an idea on how to use a child component inside a parent component.
Note: In React you want your components to be as general as possible. You would probably end up making a Text component instead of a HelloWorldText component.
Then you would pass text dynamically into the Text component using props.
Here is a CodePen Demo of this in action.
You can move the JSX part into a separate file and import that file in your component class
Here's an example
Signin.jsx
import React from 'react';
export const SigninJsx = () => {
return (
<div className="container">
<form className="form-signin">
<h2 className="form-signin-heading"> Please sign in </h2>
<br />
<label htmlFor="inputEmail" className="sr-only"> Email address
</label>
<input type="email" id="inputEmail" onChange={this.handleEmailChange} className="form-control" placeholder="Email address" required autoFocus />
<br />
<label htmlFor="inputPassword" className="sr-only"> Password</label>
<input type="password" id="inputPassword" onChange={this.handlePasswordChange} className="form-control" placeholder="Password" required />
<br />
<button className="btn btn-lg btn-primary btn-block" onClick={this.signIn} type="button"> Sign in
</button>
</form>
</div>
)
}
Signin.js
import React, { Component } from 'react';
import {SigninJsx} from './Signin.jsx';
export class Signin extends Component {
constructor(props){
super(props);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.state = {
email:'',
password:''
};
this.signIn = this.signIn.bind(this)
}
handleEmailChange(e){
this.setState({email:e.target.value})
console.log("Error Change");
}
handlePasswordChange(e){
this.setState({password:e.target.value})
}
signIn(){
alert('Email address is ' + this.state.email + ' Password is ' + this.state.password);
}
render() {
return (
<SigninJsx />
)
}
}
Please checkout this Medium link
This will be your React component declaration and
you need to import the template.js file inside here and render it in context of the component 'Abc' (index.jsx):
import template from './template';
export default class Abc extends React.Component {
render() {
return template.call(this)
}
}
Separate js file will have template as follows (template.js):
import styles from './styles.module.css';
const template = () => (
<div className={styles.outerContainer}>
<div className={styles.middleContainer}>
<div className={styles.innerContainer}>Hello, World</div>
</div>
</div>
);
export default template;
Additionally, we can import CSS modules inside the template and maintain them in serapate file as well, as follows (styles.module.css):
.outerContainer {
backgroundColor: red;
}
/* etc... etc... */
for now , it is not possible to load template from html file.

React bootstrap - Uncaught TypeError: Cannot read property 'toUpperCase' of undefined

My class is as follows:
import React from 'react';
import Input from 'react-bootstrap';
export default class FormWidget1 extends React.Component {
render() {
if (!this.props.fields) {
console.log('no fields passed');
}
else {
console.log(this.props.fields.length);
console.log(this.props.fields);
}
var formFieldList = this.props.fields.map(function(field) {
console.log("iterating");
return (
<Input type="text" placeholder="testing" label="label" />
);
});
return (
<div>
<form action="">
{formFieldList}
</form>
</div>
);
}
}
If I replace <Input /> with <input /> then there's no error.
The stacktrace only shows my app.jsx which is not useful.
What is wrong?
You need to de-structure your import of the Input jsx component.
import {Input} from 'react-bootstrap';
What this does is render to var Input = require('react-bootstrap').Input; Whereas what you previously had would render to var Input = require('react-bootstrap');
It does mention this in the documentation for React Bootstrap here:
https://react-bootstrap.github.io/getting-started.html#es6
Edit: A good hint is that the error you're getting from React is a typical error when you're trying to render as a component, something which is actually not a react component. So basically you were trying to render the object that react bootstrap returns containing all components, rather than the actual input component you wanted.

Resources