Is the correct way to access ref in react? - reactjs

Without using binding of this.say to this on button the example does not work. However I am not sure if it is right or has any side effects.
class Speak extends React.Component {
render() {
return (
<div>
<input ref={(c) => this._input = c} defaultValue="Hello World!"/>
<button onClick={this.say.bind(this) }>Say</button>
</div>
);
}
say() {
if (this._input !== null) {
alert(this._input.value);
}
}
};
ReactDOM.render(<Speak />, document.getElementById('App'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="App" />

Seems like this is required when using ES6 classes: See: Autobinding
Only difference is example above binds the method in constructor

you can utilize array functions and forget about adding .bind(this)
check out working pen
class Speak extends React.Component {
render() {
return (
<div>
<input type='text' ref='greeting'/>
<button onClick={this.say}>Say</button>
</div>
);
}
say = () => {
const { value } = this.refs.greeting;
alert(value);
return value;
};
};
ReactDOM.render(<Speak />, document.getElementById('App'));

Related

setState called everytime I type something in input

so i'm facing an issue where whenever I write something in input, handleCommentAdded is called which calls setState, re-rendering everything. This makes everything that is typed or was typed in the input to appear as comments and i want what is in the input when I click submit to appear as comment. How can I fix this?
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded:"",
}
this.handleButton = this.handleButton.bind(this);
this.handleCommentAdded = this.handleCommentAdded.bind(this);
}
handleCommentAdded(event) {
this.setState({newComment: event.target.value});
}
handleButton() {
return(
<div>
{comment}
</div>
)
}
render() {
return(
<div>
<input type="text" value={this.state.commentAdded} onChange=
{this.handleCommentAdded}/>
<div className="button">
<button
type="button"
onClick={e => this.handleButton(e)}
>
Write
</button>
</div>
)
}
}
Error is calling handleCommentAdded on onChange
set state in handleButton
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded: ""
};
this.inputRef = React.createRef();
this.handleButton = this.handleButton.bind(this);
}
handleButton() {
this.setState({ commentAdded: this.inputRef.current.value });
}
render() {
return (
<div>
<input type="text" ref={this.inputRef} />
<div className="button">
{this.state.commentAdded !== "" ? (
<div>{this.state.commentAdded}</div>
) : (
<button type="button" onClick={e => this.handleButton(e)}>
Write
</button>
)}
</div>
</div>
);
}
}
ReactDOM.render(<WriteComments />, 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' />
I created a demo where textfield value can be get by button click. Component will render everytime when setState calls. Hope it can help you!
class App extends React.Component{
state ={ inputValue:"" };
render(){
return(
<div>
<input type="text" value={this.state.inputValue} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>Submit</button>
</div>
);
}
handleChange=(e)=>{
this.setState({ inputValue: e.target.value });
}
handleSubmit=()=>{
console.log("inputValue::", this.state.inputValue);
}
}
ReactDOM.render(<App/>, 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"></div>

ReactJS: ReferenceError: submitClick is not defined

I have gone through the solutions provided regarding this problem but i still have the problem.
This is my simple code
<button onClick={submitClick} id="SubmitBtn">Request Invite</button>
then in the index.js file i have this function: which is meant to execute onClick on the submit button.
function submitClick() {
window.alert("JEBE");
}
Please help.
Please bind the function in the constructor
class App extends React.Component {
constructor(props){
super(props);
this.state={
value:""
}
this.submitClick = this.submitClick.bind(this);
this.change = this.change.bind(this);
}
change(e){
this.setState({
value : e.target.value
});
}
submitClick(){
alert(this.state.value);
}
render() {
return <div>
<form>
Email <input id="MainEmail" type="email"
placeholder ="Enter your email"
onChange={this.change}
/>
<button onClick={this.submitClick}
id="SubmitBtn">Request Invite
</button>
</form>
<br/><br/>
</div>;
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
</div>
Try using:
<button onClick={this.submitClick} id="SubmitBtn">Request Invite</button>

Render a string which contains components

I am newbie at reactJs and i am trying to build an app in which i get some results after searching .
My problem is that i have a component called ResultEntity and I am trying create a dynamically page without defined number of ResultEntity components.
I tried something like this
for(var i=0 ; i<result.length ; i++)
{
results += "<div> <ResultEntity/> </div>";
};
console.log(results);
this.setState({result: results});
And i tried to return it like ,
return (
<div>
<div dangerouslySetInnerHTML={{ __html: this.state.result }} />
</div>
);
and
return (
<div>
<div dangerouslySetInnerHTML={{ __html: this.state.result }} />
</div>
);
but both didnt work . Any idea will be appreciated . Thank you in advance
So you want to render a list of components dynamically. Here's how you can do it using .map function:
// This also can be a functional component, instead of a class
class ResultEntity extends React.Component {
render() {
const { item } = this.props
return <div>{ `${item.id} - ${item.name}` }</div>
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
items: [
{ id: 1, name: 'Bulgaria' },
{ id: 2, name: 'Germany' },
]
}
}
renderItems() {
const { items } = this.state
// Great explanations, why this work and it's rendered correctly:
// https://medium.com/byte-sized-react/component-arrays-in-react-a46e775fae7b
return items.map(item => <ResultEntity key={item.id} item={item} />)
}
render() {
// From React >= 16 it's possible to skip the wrapper `div`:
// https://stackoverflow.com/a/32157488/4312466
return <div>{ this.renderItems() }</div>
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>

Is there any reason not to pass react components as properties?

Lets say we have a react component called ThreeModule which oh so cleverly displays three arbitary react components, (or even just arbitarily defined dom elements) in a row.
We can do this by setting react elements as state elements and passing them in as properties, as suggested in this answer:
class ModA extends React.Component{
render () {
return <div> this is ModA</div>
}
}
class ModB extends React.Component{
render () {
return <div> this is ModB</div>
}
}
class ModC extends React.Component{
render () {
return <div> this is ModC</div>
}
}
class ThreeMod extends React.Component{
render() {
return (<div className = "ThreeMod">
This is ThreeMod
<div className ="left">
{this.props.moda}
</div>
<div className ="middle">
{this.props.modb}
</div>
<div className ="right">
{this.props.modc}
</div>
</div> );
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
moda: <ModA/> ,
modb: <ModB/> ,
modc: <ModC/>
}
}
render() {
function getRandomMod() {
let rand =Math.floor(Math.random() * Math.floor(4));
switch (rand) {
case 0 : return <ModA/>
case 1: return <ModB/>
case 2: return <ModC/>
default: return "random text";
}
}
return (
<div className="App">
This is App
<button onClick = {() => {
this.setState({moda: getRandomMod() }
)}}>randomise left </button>
<button onClick = {() => {
this.setState({modb: getRandomMod() }
)}}>randomise middle </button>
<button onClick = {() => {
this.setState({modc: getRandomMod() }
)}}>randomise right</button>
<ThreeMod
moda={this.state.moda}
modb={this.state.modb}
modc={this.state.modc}
/>
</div>
);
}
}
ReactDOM.render(<App />, document.body
);
div {
border: solid 1px black;
padding: 0.2em;
}
.ThreeMod {
display:flex;
flex-flow: row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id = "react"/>
This works precisely for what I'm wanting to do - what I'm wondering is - is this the wrong way to do things? Is there a reason (eg. performance) not to do things this way?
I personally don't use this approach, but the presence of element ("a React element") and node ("anything that can be rendered") in the PropTypes documentation suggests that it's supported functionality.

How to get data from Form from child component and pass it back to Parent Componet? [duplicate]

This question already has answers here:
How to access a DOM element in React? What is the equilvalent of document.getElementById() in React
(9 answers)
Closed 5 years ago.
I want to add items to the lists.Items come from Child Component's form .
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState({lists:s});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
</div>
);
}
}
What should I write in handleSubmit function such that it return list to parent component?How to access input's value from form element?
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
this.props.addList(e.target.value); //Isn't this the way to get input from Form ...//
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input> //How ref is used?????
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root'));
To access your input value by ref you can use this.refs.id.value and to pass value from child to parent component you can use props.
let {Component} = React;
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState(prevState => {
return {lists: [s, ...prevState.lists]}
});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
{this.state.lists.map((name, i) => <div key={i}>{name}</div>)}
</div>
);
}
}
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
let name = this.refs.id.value;
if(name) {
this.refs.id.value = '';
this.props.addList(name);
}
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input>
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources