I am fairly new to ReactJS, Redux and ES6, and I am trying to implement an event-handler where my chat body would hide or unhide as i click the header (kind of like what Facebook chat widget does). My problem is I cannot get the syntax correctly from a copied source. Here is my code:
import React, {Component} from 'react';
import chat from './styles.css';
import {connect} from 'react-redux';
class ChatWidget extends Component {
handleClick(event) {
console.log("test")
}
render() {
return (
<div className={chat.box}>
<div className={chat.container}>
<div onClick={onClick={this.handleClick.bind(this)}}
className={chat.header}>
<span className={chat.name}>Idol</span>
</div>
<div className={chat.body}>
This is the Body of the chat
</div>
<div className={chat.chat}>
<input type="text" placeholder="Ask anything..." />
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
user: state.activeUser
};
}
export default connect(mapStateToProps)(ChatWidget);
Error:
> 16 | <div onClick={onClick={this.handleClick.bind(this)}}
| ^
Instead of
onClick={onClick={this.handleClick.bind(this)}}
Write this:
onClick={this.handleClick.bind(this)}
The recommended way of doing bindings is in the constructor because they will be created only once, not on every render().
class Foo extends React.Component {
constructor(props) {
super(props);
this.myFn = this.myFn.bind(this);
}
myFn() {
// code goes here
}
render() {
// code goes here also
return <button onClick={this.myFn}>Look ma no .bind() here</button>;
}
}
Related
At the button click Create I want to display the room with the content (the new values that holds by the objects in the array - the value I wrote inside the inputs) but fro some reason it's not working and I can't solve it, the problem is that only the template that shows the titles Room and Type are shown without the values inside each of them
Thanks to the helpers!
App.js
import React, { Component } from 'react'
import './App.css';
import Addroom from './components/Addroom.js'
import Room from './components/Room.js'
import 'bootstrap/dist/css/bootstrap.css';
export default class App extends Component {
state={roomsList:[{room:'',type:''}]
}
create=(r,t)=> {
this.setState({roomsList:[...this.state.roomsList,{room:r,type:t}]})
}
render() {
return (
<div>
<h1>My Smart House</h1>
{this.state.roomsList.map((element)=>{
return <Room r={element.room} t={element.type} />
})}
<Addroom add={this.create}/>
</div>
)
}
}
Addroom.js
import React, { Component } from 'react'
export default class Addroom extends Component {
constructor(props) {
super(props)
}
addRoomName=(e)=> {
this.setState({room:e.target.value})
}
addType=(e)=> {
this.setState({type:e.target.value})
}
createRoom=()=> {
this.props.add(this.state.room,this.state.type);
}
render() {
return (
<div>
<input onChange={this.addRoomName} placeholder='Name Your Room'/><br/>
<input onChange={this.addType} placeholder='Whats The Room Type?'/><br/>
<button onClick={this.createRoom}>Create</button>
</div>
)
}
}
Room.js
import React, { Component } from 'react'
export default class Room extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return (
<div>
<h1>Room: {this.props.room} </h1>
<h3>Type: {this.props.type} </h3>
</div>
)
}
}
I solved the error, it was a syntax mistake, so what i did, I just asked to get the inside value from my objects in the Room.js components, So it looked like that before:
render() {
return (
<div>
<h1>Room: {this.props.room} </h1>
<h3>Color: {this.props.type} </h3>
</div>
)
}
}
and now I just fixed the syntax to make App.js component understand that I want to display the values inside the objects when I'm creating a new room with my button, because now r and t are represent the values of the variables..
render() {
return (
<div>
<h1>Room: {this.props.r} </h1>
<h3>Color: {this.props.t} </h3>
</div>
)
}
}
This is a very small mistake that is easy to understand, so it is always important to go through your code slowly and safely! Hope it will help some f.e devs in the future..
import React from "react";
checkClick = () => {
console.log("clicked");
};
class Test extends React.Component {
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>
click
</button>
</div>
);
}
}
export default Test;
How to click automatically on a button when user coming to page?
Here I want to click automatically above button.
I tried with:
document.getElementById("button").click()
which does not work.
You can use a ref which gives you an instance of the dom element, where you can call the click() method.
If you aren't familiar with refs, you can read all about them here: https://reactjs.org/docs/refs-and-the-dom.html
import React, { Component } from 'react'
class Test extends Component {
constructor(props) {
super(props)
this.button = React.createRef()
}
componentDidMount() {
this.button.current.click()
}
checkClick() {
console.log('clicked')
}
render() {
return (
<div>
<button ref={this.button} onClick={this.checkClick}>Click me!</button>
</div>
)
}
}
export default Test
First of all, I do not recommend you to create functions outside of React component class. In your case, you are not able to use it like this.checkClick because the checkClick function is declared outside of your React component.
The second thing, working with real DOM inside of React is basically, let's say, antipattern. React provides virtual DOM and works with it, so, I recommend you to learn about React ref API.
For your case, you can use the lifecycle componentDidMount() method. It is being called (AUTOMATICALLY, for sure) when the component has finished its first render, so, all refs are already available here and all children elements are beind mounted and present in DOM.
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
document.getElementById("button").click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
or, using refs
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
this.button.click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button ref={button => this.button = button} onClick={this.checkClick}>click</button>
</div>
)
}
}
Use componentDidMount for that,
import React from 'react';
class Test extends React.Component {
componentDidMount(){
this.checkClick();
}
checkClick () {
console.log("clicked");
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
export default Test;
This is my code:
generateAlert = () => {
alert('hi');
}
return <Tile
click={(index)=>{this.generateAlert}}
title={tile.title}
value={tile.value}
key={tile.id}
/>
This is the error I'm getting:
Expected an assignment or function call and instead saw an expression no-unused-expressions
Search for the keywords to learn more about each error.
First, I do wonder if in your Component you have an array of Tile data, and you want to render a Tile for each entry of the array (I thought so because you added the key prop to Tile).
Anyways, I made an example similar to what you want to achieve, and it's working. Look at this:
const Tile = (props) => {
return (
<div className="Tile">
<h3>{props.title}</h3>
<div onClick={props.click}>
{props.value}
</div>
</div>
);
}
class App extends React.Component {
constructor(props) {
super(props);
}
generateAlert = () => {
alert("Hi");
}
render() {
return (
<Tile
click={this.generateAlert}
title={"This isa a Title"}
value={"This is the value"} />
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
#import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
Now, I may help you in a deeper way if you would post the code of the Component that wants to render Tile; maybe, there are some error in that.
Hei!
If it's a function invocation inside your component's onClick function, you need to add () after this.generateAlert in your component
So it's gonna be like:
return <Tile
click={(index)=>{this.generateAlert()}}
title={tile.title}
value={tile.value}
key={tile.id}
/>
Otherwise, you can use your function as a onClick callback per se.
In that case you need to have it like this:
return <Tile
onClick={this.generateAlert}
title={tile.title}
value={tile.value}
key={tile.id}
/>
Cheers!
I will do in this way:
Q: why I export Tile to new component?
A: As each component should be as short as possible. There is a many advantages to doing in this way
like: "easy to find bugs (testing)".
import React, { Component } from "react";
import Tile from "./Tile";
import "./App.css";
class App extends Component {
constructor(props) {
super(props);
this.generateAlert = this.generateAlert.bind(this);
}
generateAlert = () => {
alert("Hi");
};
render() {
return (
<Tile
click={this.generateAlert}
title={"This isa a Title"}
value={"This is the value"}
/>
);
}
}
export default App;
and file Tile.js:
import React, { Component } from "react";
export default class Tile extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<button onClick={this.props.click}>click me</button>
<p>{this.props.title}</p>
<p>{this.props.value}</p>
</div>
);
}
}
This file Tile.js are ready for future addons but if you want to use only like it is now I would recommend to change into stateless component:
import React from "react";
const Tile = props => {
return (
<div>
<button onClick={props.click}>click me</button>
<p>{props.title}</p>
<p>{props.value}</p>
</div>
);
};
export default Tile;
I want to call WOW when a ReactJS Component has loaded
The WOW Javascript is referenced at the bottom of the HTML on the inital HTML load.
the Javascript way to initiate is
new WOW().init();
and I thought it would be good to call this on "componentDidMount()"
my component code is:
import * as React from 'react';
class Banner extends React.Component {
componentDidMount() {
new WOW().init(); //This does not work "[ts] Cannot find name "WOW"
}
shouldComponentUpdate() {
return false;
}
render() {
return (
<div className="banner-section">
<div className="an-home-img-container banner-1">
<div className="overlay"></div>
<div className="home-banner-content text-center">
<div className="container">
<h1 className="wow fadeInDown animate hidden">
Some <span>Text</span> Here
</h1>
<button className="an-btn an-btn-default btn-big wow fadeIn hidden">Expole Us</button>
</div>
</div>
</div>
</div >
)
} }
export default Banner;
How can I call a JS function that isn't imported?
You can declare the variable before using it:
declare var WOW: any;
class Banner extends React.Component {
componentDidMount() {
new WOW().init();
}
// ...
}
Note that this will type WOW as any so you will lose type checking. If you need type checking you can declare WOW with a type instead of any:
interface WOW {
init: () => void
}
interface WOWConstructor {
new(): WOW
}
declare var WOW: WOWConstructor;
class Banner extends React.Component {
componentDidMount() {
new WOW().init();
}
// ...
}
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.