I'm very new to reactjs and I've using AngularJS upto now. Currently i'm trying to learn reactjs.
I have a html code like this
<div class="status_bar">
<div>
<label class="status_head">Post as: John Smith</label>
<input class= 'post_data_input' placeholder="I'm seeking feedback for..."/>
.
<div class="status_down">
<button class="public_btn">Public</button>
<button class="post_btn">Post</button>
<img class='cam_btn' src="img/cam.png" alt=""/>
</div>
</div>
</div>
I want to save whatever typed in the input field to an array and access that data from the array to show somewhere else. How can I do this in reactjs?
Thanks inadvance.
you can get it by two ways , either:
1- assign ref value myInput to input , and retrieve it by this.refs.myInput.value
2 - IF you are getting value on firing its own event , retrieve it by event.target.value
SAMPLE :
class App extends React.Component {
constructor() {
super(...arguments);
this.state= {};
}
//Method-1 : this.refs.myInput.value
onClick() {
alert('You enter : '+this.refs.myInput.value);
}
// METHOD-2 : event.target.value
onKeyUp(event) {
const value = event.target.value;
this.setState({inputSize: value.length || ''})
}
render() {
return (<div class="status_bar">
<div>
<label class="status_head">Post as: John Smith </label>
<input ref="myInput" className= 'post_data_input' placeholder="I'm seeking feedback for..." onKeyUp={this.onKeyUp.bind(this)} />
.<label>{this.state.inputSize}</label>
<div className="status_down">
<button className="public_btn" onClick={this.onClick.bind(this)}>Public</button>
<button className="post_btn" onClick={this.onClick.bind(this)}>Post</button>
<img className='cam_btn' src="img/cam.png" alt=""/>
</div>
</div>
</div>)
}
}
// -- Mount component
ReactDOM.render(<App />, document.querySelector('section'))
<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>
<section></section>
Related
I am making a React page which has a post and comments on the post. Now the onChange on being triggered re-renders the whole class which makes the typing in input slow.
Now, if the is declared in a separate class and the value entered in the input there can be sent to the main class for API call. But I am not able to do this. Can anyone help me?
Below is code for my comment section of the screen.
commentChange(html) {
this.setState({ post_comment: html})
}
<div className="post-comments">
<div className="post-comments-head">
<div>Comments ({this.state.comments.length})</div>
</div>
<div className="comments">
{this.createCommentList(this.state.comments2)}
</div>
</div>
<div className="post-commenting">
{this.state.reply == -1 ? <span>Comment as {this.state.name}</span>
: this.commentBy()}
<div className="write-comment-post">
<ReactQuill
data-gramm_editor="false"
onChange={this.commentChange}
value={this.state.post_comment}
className="post_comments_x"
placeholder="Write a comment"
ref={(ip) => this.myInp = ip}
autoFocus={true}
theme=""
/>
<div className="comments-submit">
<button className="submit-comment"
onClick={() => this.submitComment(this.state.reply)}
disabled={!enabledComment}>
Comment
</button>
</div>
</div>
</div>
The createCommentList function takes comments and returns a nested list of comments. Below is the section where new comment is added.
How to solve this because it is making typing a new comment very slow.
<div className="write-comment-post">
<ReactQuill
data-gramm_editor="false"
onChange={this.commentChange}
value={this.state.post_comment}
className="post_comments_x"
placeholder="Write a comment"
ref={(ip) => this.myInp = ip}
autoFocus={true}
theme=""
/>
create a seperate component for this
and only onn enter call parennt function else onchange it will trigger
I'm hoping you encounter the same issue of mine. I have react code that need a jquery event like (click, change). here is my code.
export default class SamplePreviewComponent extends React.Component<Props, any> {
constructor(props) {
super(props);
}
componentDidMount() {
this.renderChoiceButton();
}
renderChoiceButton() {
$("input.st").on("click", function() {
let value = $(this).val();
this.props.addDependentSample(value);
});
}
render() {
const { sampleTree } = this.props;
return (
<div className="row pl-1 pr-1 pt-0 mb-1">
<div className="columns bg-black20 pt-1 pb-1 border-radius-sm">
<div className="mb-1">
<p className="subheader">
<strong>
<small>SAMPLE #1</small>
</strong>
</p>
{sampleTree.root.label.trim().length > 0 && <h4>{sampleTree.root.label}</h4>}
{sampleTree.root.subLabel &&
sampleTree.root.subLabel.trim().length > 0 && (
<span className="subheader">
<small>
<strong>{sampleTree.root.subLabel}</strong>
</small>
</span>
)}
</div>
<div>
<div
dangerouslySetInnerHTML={{ __html: sampleTree.root.generatedHtml }}
className="red"
/>
</div>
</div>
</div>
);
}
}
if you check my return value of my component. there is dangerouslySetInnerHTML added. The output is like this
<div>
<div class="fancy-checkbox fancy-hover small mb-0">
<input type="checkbox" class="st" id="_0" name="17[]" value="1">
<label for="_0">1</label>
</div>
<div class="fancy-checkbox fancy-hover small mb-0">
<input type="checkbox" class="qt" id="_1" name="17[]" value="2">
<label for="_1">2</label>
</div>
</div>
When the user click the checkbox. I'm going to add and event using a jquery
renderChoiceButton() {
$("input.st").on("click", function() {
let value = $(this).val();
this.props.addDependentSample(value);
});
}
I get an error Cannot read property 'addDependentSample' of undefined. Maybe, because it comes from the react props and the jquery cannot read it. How can I add event using jquery that will connect the function to react?
There are a few ways you can resolve this error - a simple approach would be to store a reference to your component instance (ie componentInstance as shown below), and then access the component's props through that instance, like so:
renderChoiceButton() {
// Store reference to component for access in click handler
const componentInstance = this;
$('input.st').on('click', function() {
let value = $(this).val();
// Access props for the component via componentInstance
componentInstance.props.addDependentSample(value);
});
}
I am new in world of coding and i have a problem with my React code.
What is on my code is a search bar. I want when i click on the search button to appear a text area to put some text and when i press X to display the first button(search). First time i use getInitialState with 2 renders(renderOpen and renderNormal) and works! But now i want to make it all in one render and to display it. The code is propretly good but is displaying
2 object and i want to display all in one object.
Thanks!!!
import React from 'react';
import ReactDOM from 'react-dom';
var Button = React.createClass({
getInitialState: function() {
return {search:false}
},
close: function(){
this.setState({search:false})
console.log('test1');
},
open: function(){
this.setState({search:true})
console.log('test2');
},
renderNormal: function (){
return(
<div className="mainDiv">
<div className="search-close">
<img src="search2.png" className="search-button" alt="" onClick={this.open}/>
<layer onClick={this.open} className="layer">
<span className="defaultText">Search
</span>
</layer>
</div>
<div className="search-open">
<span className="layer2">
</span>
<input type="image" src="search2.png" className="search-button2"/>
<input type="text" placeholder=" Search" className="text-area"/>
<span className="close-area" onClick={this.close}>x
</span>
</div>
</div>
)
},
render: function() {
if(this.state.search) {
return this.renderNormal(
this.props.search-close);
}else {
return this.renderNormal(
this.props.search-open);
}
}
});
const element = <div>
<Button/>
</div>;
ReactDOM.render(
element,
document.getElementById('root')
);
You want renderNormal to return just one of the two, like this:
renderNormal: function (){
if(this.state.search) {
return(
<div className="mainDiv">
<div className="search-open">
<span className="layer2">
</span>
<input type="image" src="search2.png" className="search-button2"/>
<input type="text" placeholder=" Search" className="text-area"/>
<span className="close-area" onClick={this.close}>x
</span>
</div>
/div>)
}
else {
return (
<div className="mainDiv">
<div className="search-close">
....
</div>
/div>)
}
}
With a bit of effort you could avoid repeating the mainDiv container, but the key lesson here is that the render method is pure Javascript, and you can use if statements inside of it. The JSX code that looks like HTML is actually just a special syntax for making Javascript objects... which will be used by the top levels of React to manipulate the DOM just like the HTML. (Well, not quite, but pretty close.)
I have a quiz form here and would like to add input fields for questions when a user clicks the "Add a question" button.
I've been playing around with the code and have been able to populate the state object with some text. Obviously, the goal is to have this be an input component and then somehow rendering this to the screen.
What I'm struggling with is how to render an actual element to the page. I know it's done in the render method of the component just not exactly sure how.
I think I'm getting close. Any help would be appreciated. The code is below.
Thanks!
var QuizForm = React.createClass({
getInitialState : function() {
return { questions : [] }
},
createQuestion : function() {
this.state.questions.push("Test");
// Adds "Test" to state object.
this.setState({
questions : this.state.questions
});
},
render : function() {
return (
<div className="quiz-form well text-center">
<h1 className="header text-center">Quiz Form</h1>
<ul>
{/* Would like question inputs to show up here */}
</ul>
<button onClick={this.createQuestion} className="add-question-btn btn btn-primary" style={{ marginTop : 40 }}>Add Question</button>
</div>
);
}
Just map your this.state.questions array to the HTML element you want.
For instance, if you want to render <li> elements:
render : function() {
return (
<div className="quiz-form well text-center">
<h1 className="header text-center">Quiz Form</h1>
<ul> // magic happens now
{this.state.questions.map(function(state) {
return <li>{state}</li>
})}
</ul>
<button onClick={this.createQuestion}
className="add-question-btn btn btn-primary"
style={{ marginTop : 40 }}>Add Question</button>
</div>
);
}
See an example.
If you want to render <input> tags, you can use the same technique above, but be mindful of the fact that React treats it as a controlled component.
A React best practice would be to map your state.questions array to a dynamically generated HTML component such as:
render : function() {
return (
<div className="quiz-form well text-center">
<h1 className="header text-center">Quiz Form</h1>
<ul> // magic happens now
{this.state.questions.map(function(state) {
return <li key={state.someId}>{state.question}</li>
})}
</ul>
<button onClick={this.createQuestion}
className="add-question-btn btn btn-primary"
style={{ marginTop : 40 }}>Add Question</button>
</div>
);
}
Please keep in mind that when mapping and rendering dynamic objects in React it's always good to insert a key for each mapped object. So make sure to create that when you're creating the content.
Best Regards,
If my api takes the query as http://localhost:8000/api/v1/rental/?place__startswith=kathmandu then how can i do generic search in reactjs. What i tried is i passed the default parameter as search(query=kathmandu) so that the result of place named kathmandu will be listed by default and when user types place name that they want to search then it should display those places instead of kathmndu. But i am getting an error saying Uncaught ReferenceError: kathmandu is not defined. How can i resolve this problem?
componentWillMount(){
this.search();
}
search(query=kathmandu){
let url = 'http://localhost:8000/api/v1/rental/?place__startswith=query';
Request.get(url).then((response) => {
console.log('response',response.body.objects);
this.setState({
place:response.body.objects
});
});
}
searchUpdated(term){
console.log('term is',term);
this.search(term);
}
render() {
var margin = { marginTop : '13em' };
let location = _.map(this.state.place, (place) => {
return(
<div className="searchResult">
<li>{place.place}</li>
<li>{place.city}</li>
</div>
)
});
return(
<div className = "container">
<div className="content text-align-center">
<div className="row text-xs-center">
<div className="middle-text" style={margin}>
<h1 className="welcome"><span>Welcome </span></h1>
<button ref="test" className="btn how-it-works" onClick={this.handleClick}>Search Space</button>
</div>
</div>
</div>
<div id="mySearch" className="overlay" onKeyDown={this.handleKeyDown}>
<button className="btn closebtn" onClick={this.handleClick}>x</button>
<div className="overlay-content">
<SearchInput ref="searchInput" className="search-input" onChange={this.searchUpdated} />
<ul>{location}</ul>
</div>
</div>
</div>
);
}
}
I think what you're looking for is encodeURIComponent.
search( query='kathmandu' ){
And:
let url = 'http://localhost:8000/api/v1/rental/?place__startswith=' + encodeURIComponent(query);
NB as your query string actually does only contains letter, you don't need encodeURIComponent for that example, but you might need it in other cases.