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.
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);
}
I want a comment to be posted one after another but not exactly sure how to implement it. Right now, the new comment is replacing the old one. After reading some posts, I think this.props.children could be the answer but stil somewhat confused, so please let me know the best way to implement what I want to. Thanks.
Comment.js:
import React from 'react';
import { Display } from './Display';
export default class Comment extends React.Component {
constructor(props) {
super(props);
this.state = { buttonClicked: false, count: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ buttonClicked: true , count : this.state.count + 1 });
console.log('Button clicked');
}
render() {
const comment_form =(
<div className="posts" >
<input type="text" id="comment-box" name="comment" placeholder="Say something nice." />
<button className="submit-button" type="button" onClick={this.handleClick}>Comment</button>
</div>
);
if (this.state.buttonClicked) {
return (
<div>
{comment_form}
<Display commentNumber={this.state.count} />
</div>
);
} else {
return (<div> {comment_form} </div>);
}
}
}
Display.js:
import React from 'react';
import './App.css';
export class Display extends React.Component {
constructor(props){
super(props);
}
render() {
console.log('display rendered');
const comments = (
<div className="display-comments">
<p>Comment {this.props.commentNumber} :{ document.getElementById('comment-box').value }</p>
</div>
);
return (
<div>
{comments}
</div>
);
}
}
Use the map function to dynamically render the elements.
Link: https://reactjs.org/docs/lists-and-keys.html
Consider the following code:
import React from 'react';
class TestForm extends React.Component {
constructor(props) {
super(props);
}
_submitTest(e) {
e.preventDefault();
this.context.router.transitionTo('/test-next-page', {param_test: 'Test Data'});
}
render() {
return (
<div className="post-content row">
<form className="test-form" method="post" onSubmit={this._submitTest.bind(this)}>
<input type="submit" value="Submit" className="btn btn-primary btn-lg"/>
</form>
</div>
);
}
}
TestForm.contextTypes = {
router: React.PropTypes.object
}
export default TestForm;
the this.context.router.transitionTo() line in the _submitTest() function send me to the test-next-page page/component but i am not seeing the param value in the component!
Am I doing anything wrong in the second parameter of this.context.router.transitionTo()?
After tried different way, I found a solution. I have updated the function this way:
_submitTest(e) {
e.preventDefault();
const my_json_obj = {param_test: 'Test Data'};
this.context.router.transitionTo({
pathname: '/test-next-page',
state: my_json_obj
});
}
Once I moved to the corresponding component of test-next-page path, I found the data in the props. Just like this:
class TestNextPage extends React.Component {
constructor (props) {
super(props);
}
async componentWillMount() {
console.log(this.props); // Here I found the data in state under location object
}
}
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'))
I am trying to pass data from one component to another. but it has no parent child relation and it is independent from each other. I want to do it using flux not redux. Can anyone help me to do this? below are my code.
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The other file is where i want to send the EmpNumber is below,
class EmpDetail extends React.Component {
render() {
return (
<div className="container">
<input type="text"/>
</div>
);
}
}
export default EmpDetail;
Assuming you have already implemented the flux architecture in your app.
your 1st component will be like this.
import React from 'react';
import UserAction from '../../Actions/UserActions';
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
UserAction.employeeNumb(this.state.Empnumber);
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The Actions file will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
export default {
employeeNumb(Data){
dispatch({ actionType:'EMPNO',data:Data});
}
}
The Store will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
import AppConstants from '../Constants/AppConstants';
import {EventEmitter} from 'events';
const CHANGE_EVENT = 'change';
var a=0;
const UserStore = Object.assign(EventEmitter.prototype,{
emitChange(){
this.emit(CHANGE_EVENT)
},
addChangeListener(callback){
this.on(CHANGE_EVENT,callback);
},
removeChangeListener(callback){
this.removeListener(CHANGE_EVENT,callback)
},
setEmpData(data){
a=data;
},
getEmpData(){
return a;
}
});
dispatcherIndex:register((action)=>{
switch (action.actionType) {
case AppConstants.EMPNO:
UserStore.setEmpData(action.data);
UserStore.emitChange();
break;
}
UserStore.emitChange();
});
export default UserStore;
The dispatcher file
import {Dispatcher} from 'flux';
const flux = new Dispatcher();
export function register(callback){
return flux.register(callback);
}
export function dispatch(actionType,action){
flux.dispatch(actionType,action);
}
and the 2nd Component file looks like
import React from 'react';
import Store from '../../Store/UserStore';
class EmpDetail extends React.Component {
constructor(props){
super(props);
this.state={
empno:''
};
}
componentDidMount(){
Store.addChangeListener(this._onChange);
}
componentWillUnmount = () =>{
Store.removeChangeListener(this._onChange);
}
_onChange = () =>{
this.setState({empno:Store.getEmpData()});
}
render() {
return (
<div className="container">
<input type="text"/>
<input type="button" onClick={()=>{console.log(this.state.empno);}}/>
</div>
);
}
}
export default EmpDetail;
What you have tried might be slightly different but this is the normal flow for what you are looking for.