import React, { Component } from 'react'
class Example extends React.Component {
constructor(props){
super(props)
this.handleWinner = this.handleWinner.bind(this);
}
handleWinner(event){
event.preventDefault();
alert("Buttet Pressed")
}
render() {
return (
<td key=1><button onClick={this.handleWinner}>Click Me</button></td>
)
}
My function is Not Dispatching on Button Click
Your render function is missing a }.
render() {
return(
<td key=1><button onClick={this.handleWinner}>Click Me</button></td>
)
}
You haven't closed the brackets properly
class Example extends React.Component {
constructor(props) {
super(props);
this.handleWinner = this.handleWinner.bind(this);
}
handleWinner(event) {
event.preventDefault();
alert("Buttet Pressed")
}
render() {
return <div key=1>
<button onClick={this.handleWinner}>Click Me</button>
</div>
}
}
ReactDOM.render(<Example />, document.getElementById('app'))
Related
I am new in React Js and want to call the parent method from the child method.
There is a class login.jsx when someone clicks on submits button then a method changeUser in FirstPage.jsx should be invoked but when I try the online solution I am getting same error again and again that this.props.changeUser is not a function.
Login.jsx (child class)
import React, { Component } from 'react';
class Login extends Component {
constructor(props){
super(props);
this.state ={
user : null
}
this.onNameChange = this.onNameChange.bind(this);
this.onHandleClick = this.onHandleClick.bind(this);
}
onNameChange = (event)=>{
this.setState({
user:event.target.value
})
}
onHandleClick=(event)=>{
event.preventDefault();
this.props.changeUser("hello");
}
render() {
return (
<form>
<h3>Sign In</h3>
<div>
<label>User Name</label>
<input type="text" name="userId" placeholder="Enter User name" onChange ={this.onNameChange}/>
</div>
<button className="btn btn-primary btn-block" onClick={this.onHandleClick}>Submit</button>
</form>
);
}
}
export default Login;
FirstPage.jsx (parent class)
import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser =(x)=>{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage;import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser =(x)=>{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage;
I am getting an error that TypeError: this.props.changeUser is not a function
Please help me.
try to avoid using a lambda expression within you class component. Just create a simple member function:
import React, { Component } from 'react';
import Login from './Login';
class Firstpage extends Component {
constructor(props){
super(props);
this.state=
{
user:null
}
this.changeUser = this.changeUser.bind(this)
}
changeUser(x) // Try to declare this as member function
{
console.log(x)
}
render() {
return (
<div>
<Login changeUser ={this.changeUser}/>
</div>
);
}
}
export default Firstpage
You are making a mistake here while binding , inside constructor
//WRONG
this.onNameChange = this.onNameChange.bind(this);
this.onHandleClick = this.onHandleClick.bind(this);
//RIGHT
this.onNameChange = onNameChange.bind(this);
this.onHandleClick = onHandleClick.bind(this);
CODE:
constructor(props){
super(props);
this.state ={
user : null
}
this.onNameChange = onNameChange.bind(this);
this.onHandleClick = onHandleClick.bind(this);
}
onmouse is not working when I hover my mouse on the text in h1 tag, but its printing value in the console when I click on it.
import React, {
Component
} from 'react';
class App extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick = (event) => {
let word = event.target.innerText;
console.log(word)
}
render() {
return (<div>
<div className="App">
<h1 onMouseOver = {this.handleClick}>hover Me</h1>
</div>
</div>);
}
}
export default App;
the code works fine, only the "super(props)" part has been deprecated, another trick: when you use Arrow functions you don't need to bind the function in the constructor. This is the complete code:
import React, { Component } from 'react';
class YourComponent extends Component {
constructor(props) {
super();
this.state={};
}
handleClick = (event) => {
let word = event.target.innerText;
console.log(word)
}
render() {
return (
<div>
<div className="App">
<h1 onMouseOver={this.handleClick}> hover Me </h1>
</div>
</div>
);
}
}
export default YourComponent;
Enjoy ;)
UPDATE: My code checked out just fine. The issue was that a stopPropagation() was called in a separate Javascript library that prevented my onClicks from working.
--
I have a "MenuLink" react component in which I've added an onClick listener to an 'a' tag. The "MenuLink" component is imported from a "MenuItem" component which is imported from a "MainMenu" component (see below).
When I click on link generated from MenuLink, nothing happens. No errors, no nothing. I would expect to see "handleClick" in my console and for the link to be prevented from executing.
MenuLink.js
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
export default MenuLink;
MenuItem.js
import MenuLink from './MenuLink.js';
class MenuItem extends React.Component {
constructor(props) {
super(props);
this.state = props.item;
}
render(key) {
const item = this.state;
return(
<li
key={key}
>
<MenuLink
link={item}
/>
</li>
);
}
}
export default MenuItem;
MainMenu.js
import MenuItem from '../components/MenuItem.js';
class MainMenu extends React.Component {
state = {
menu: []
}
render() {
return(
<ul className="menu">
{this.state.menu.map(function(menuItem, i) {
return(
<MenuItem key={i} item={menuItem} />
)
})}
</ul>
);
}
componentDidMount() {
fetch('/api/menu_items/main')
.then(res => res.json())
.then((data) => {
this.setState({ menu: data })
})
.catch(console.log)
}
}
export default MainMenu;
The below snippet shows that it does work as expected. No changes were made.
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
class MenuItem extends React.Component {
constructor(props) {
super(props);
this.state = props.item;
}
render(key) {
const item = this.state;
console.log(key) // Undefined. Don't do this
return(
<li
key={key}
>
<MenuLink
link={item}
/>
</li>
);
}
}
class MainMenu extends React.Component {
state = {
menu: [{
alias: 'test',
title: 'test'
},
{
alias: 'test2',
title: 'test2'
}]
}
render() {
return(
<ul className="menu">
{this.state.menu.map(function(menuItem, i) {
return(
<MenuItem key={i} item={menuItem} />
)
})}
</ul>
);
}
}
ReactDOM.render(<MainMenu />, document.getElementById('root'))
<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"/>
Please check this example:
import React from "react";
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
// this.state = props.link;
this.state = {
link: {alias: "http://www.google.com", title: 'Google'}
}
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state.link;
return (
<div>
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
</div>
);
}
}
export default MenuLink;
This approach should work
class MenuLink extends React.Component {
constructor(props) {
super(props);
//this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick = e => {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
export default MenuLink;
Can I use children in React Container or is it wrong?
For example, I have a list of buttons(ActionButton) that are grouped together (ActionMenu).
import React from 'react';
class App extends React.Component {
render() {
return (
<ActionMenu>
<ActionButton name="New" icon="add" />
<ActionButton name="Delete" icon="remove" />
</ActionMenu>
)
}
}
class ActionMenu extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert('Click!');
}
render() {
return React.Children.map(this.props.children, (button) =>
React.cloneElement(button, {
onClick: this.handleClick
})
);
}
}
function ActionButton({ name, icon, onClick }) {
return <button class={icon} onClick={onClick}>{name}</button>
}
You can use children regardless of whether it's a component of container.
"[children are] especially common for components like Sidebar or Dialog that represent generic 'boxes'."
In your case you have a menu, which falls into this category.
https://reactjs.org/docs/composition-vs-inheritance.html
I think this is what you are after. Actually you should just put the children in its closest parent instead of its grandpa.
import React from 'react';
import { render } from 'react-dom';
function ActionButton({ name, handleClick }) {
return <button onClick={handleClick}>{name}</button>
}
class ActionMenu extends React.Component {
constructor(props) {
super(props);
}
handleClick = () => {
alert('Click!');
}
render() {
return (
<div>
<ActionButton name="add" handleClick={this.handleClick}/>
<ActionButton name="remove" handleClick={this.handleClick} />
</div>
);
}
}
class App extends React.Component {
render() {
return (
<ActionMenu />
)
}
}
render(<App />, document.getElementById('root'));
You can try to run it in sandbox.
By the way, using bind is quite redundant now, we can use public class fields syntax, which is already ECMA stage 2.
it is necessary in the method clickSubmitComment(), write logic added to the array of comments text of the textarea, I'm still learning tell me how or share a link.
comment.jsx:
import React from 'react';
export default class Comment extends React.Component {
constructor(props){
super(props);
}
render() {
const comment = this.props.comment.map((commentForm, index) => {
return <CommentForm key={index} {...commentForm}/>
});
return (
<div className="media-body">{comment}<br></br></div>
);
}
}
and, commentForm.jsx:
import React from 'react';
export default class CommentForm extends React.Component {
constructor(props){
super(props);
this.clickSubmitComment = this.clickSubmitComment.bind(this);
this.comments = [];
}
clickSubmitComment() {
textarea -> comments -> send props to comment.jsx and view?
}
render() {
return (
<div><textarea className="form-control" rows="3"></textarea><br></br>
<button type="submit" className="btn btn-primary" onClick={this.clickSubmitComment}>Submit</button></div>
);
}
}
import React from 'react';
export default class Comment extends React.Component {
constructor(props){
super(props);
}
handleCommentChange(text){
// do something with the text
}
render() {
const comment = this.props.comment.map((commentForm, index) => {
return <CommentForm key={index} {...commentForm} handleCommentChange = {this.handleCommentChange.bind(this)}/>
});
return (
<div className="media-body">{comment}<br></br></div>
);
}
}
import React from 'react';
export default class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
text: ''
};
this.updateState = this.updateState.bind(this);
}
updateState(e){
this.setState({text: e.target.value});
}
render() {
return (
<div><textarea value={this.state.text} className="form-control" onChange={this.updateState()} rows="3"></textarea><br></br>
<button type="submit" className="btn btn-primary" onClick={this.props.handleCommentChange(this.state.text)}>Submit</button></div>
);
}
}
Add onChange to your textarea and save its value to the state, and then onButton click get the state value. Something like this :
class Test extends React.Component {
constructor(props){
super(props);
this.state = {
comment: ""
}
}
handleComment(e){
this.setState({comment: e.target.value});
}
clickSubmitComment(){
let comment = this.state.comment;
//Do what you will with the comment
}
render(){
return (
<div>
<div><textarea className="form-control" rows="3" onChange={this.handleComment.bind(this)}>{this.state.comment}</textarea><br></br>
<button type="submit" className="btn btn-primary" onClick={this.clickSubmitComment.bind(this)}>Submit</button></div>
</div>
)
}
}
React.render(<Test />, document.getElementById('container'));
Here is a fiddle.