ReactJS - moving list items between components - javascript

I am trying to create two components, one that holds the results of an API call from iTunes. I want to be able to click on any one of the items and move it to the empty component, moveResults, and then move it back to searchResults if it is clicked again. From other exercises, I feel like I am close, however I keep getting an error about the this.handleEvent = this.handleEvent.bind(this). Any ideas as to where I might have gone wrong and some possible solutions?
var App = React.createClass({
getInitialState: function() {
return {
searchResults: [],
moveResults: []
}
},
this.handleEvent = this.handleEvent.bind(this);
showResults: function(response) {
this.setState({
searchResults: response.results,
moveResults: []
})
},
search: function(URL) {
$.ajax({
type: 'GET',
dataType: 'json',
url: URL,
success: function(response) {
this.showResults(response);
}.bind(this)
});
},
handleEvent(trackId) {
const isInSearchResults = this.state.searchResults.includes(trackId);
this.setState({
searchResults: isInSearchResults ? this.state.searchResults.filter(i => i !== trackId) : [...this.state.searchResults, trackId],
moveResults: isInSearchResults ? [...this.state.moveResults, trackId] : this.state.moveResults.filter(i => i !== trackId)
});
},
componentDidMount() {
this.search('https://itunes.apple.com/search?term=broods')
},
render: function(){
return (
<div>
<Results searchResults={this.state.searchResults} handleEvent={this.handleEvent}/>
<Results searchResults={this.state.moveResults} handleEvent={this.handleEvent} />
</div>
);
}
});
var Results = React.createClass({
render: function(){
let handleEvent = this.props.handleEvent;
var resultItems = this.props.searchResults.map(function(result) {
return <ResultItem key={result.trackId} trackName={result.trackName} onClick={() => handleEvent(resultItems.id)} />
});
return(
<ul>
{resultItems}
</ul>
);
}
});
var ResultItem = React.createClass({
render: function(){
return <li> {this.props.trackName} </li>;
}
});
ReactDOM.render(
<App />, document.getElementById('root')
);

Related

React not loading data for Ajax call

I have built a React component and I want to put data in it when the component loads but I constantly get the Array as empty. To my understanding if I have to put data in a component I should do so in ComponentDidMount method.
Below is my code.
var Home = React.createClass({
componentDidMount(){
console.log('component mount');
var self = this;
var str = "junk string";
$.ajax({
url: "http://localhost:9000/checkoutcart/data/",
type : "get",
data : {
ajaxid: 4,
UserID: str
},
}).then(function (data) {
self.setState({movieItem: data});
});
},
getInitialState: function() {
console.log('getInitialState component mount');
return {movieItem:[]};
},
render: function() {
return (
<div>
<div>
<div>
<ol>
{this.state.movieItem.map(stuff => (
<li><h4>{stuff.title}</h4></li>
))}
</ol>
</div>
</div>
</div>
);
}
});

How to track state of parent component from child component in ReactJs?

I have a page with photoalbums, and I need edit each album by click on the edit button in album component. I can't understand how to communicate between components if I have no common store(redux for example)
How to track state of parent component from child component - Modal?
var AlbumsPage = React.createClass({
render: function ()
{
return(
<div>
<AlbumList url="Album/List"/>
</div>
);
}
});
var AlbumList = React.createClass({
componentDidMount: function ()
{
$.ajax({
url: this.props.url,
dataType: 'json',
method: "POST",
cache: false,
success: function (data) {
this.setState({ data: data.Albums });
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function()
{
return this.getAlbumListState();
},
getAlbumListState: function()
{
return {
data: [],
currentAlbum: null,
showModal: false
}
},
setCurrentAlbum: function(album){
this.state.currentAlbum = album;
},
setShowModal : function(val){
this.state.showModal = val;
},
getShowModal: function(){
return this.state.showModal;
},
render: function () {
var albums = this.state.data.map(function(album) {
return (
<Album key={ album.Id } title={ album.Title } getShowModal={ this.getShowModal } setCurrentAlbum={ this.setCurrentAlbum } setShowModal={ this.setShowModal }></Album>
);
}, this);
return (
<div>
<div>
{ albums }
</div>
<AlbumModal showModal={ this.state.showModal } currentAlbum={ this.state.currentAlbum }/>
</div>
);
}
});
var Album = React.createClass({
open : function()
{
console.log("open fired");
console.log(this.props.getShowModal());
if (this.props.getShowModal()) {
this.props.setShowModal(false);
this.props.setCurrentAlbum(null);
} else {
this.props.setShowModal(true);
this.props.setCurrentAlbum(this.props.album);
}
},
render: function () {
return (
<div className="col-sm-3 col-md-3">
<div className="thumbnail">
<div className="caption">
<h3>{ this.props.title }</h3>
<p>
<a onClick={ this.open }><span className="glyphicon glyphicon-pencil"></span></a>
<a><span className="glyphicon glyphicon-trash"></span></a>
</p>
</div>
</div>
</div>
);
}
});
var AlbumModal = React.createClass({
getInitialState: function() {
return {
showModal: this.props.showModal,
currentAlbum: this.props.currentAlbum
};
},
close: function() {
this.setState({ showModal: false });
},
open: function() {
this.setState({ showModal: true });
},
render: function() {
return (
<div>
<ReactBootstrap.Modal show={this.state.showModal} onHide={this.close}>
<ReactBootstrap.Modal.Header closeButton>
<ReactBootstrap.Modal.Title>Modal heading</ReactBootstrap.Modal.Title>
</ReactBootstrap.Modal.Header>
<ReactBootstrap.Modal.Body>
<h4>Text in a modal</h4>
</ReactBootstrap.Modal.Body>
<ReactBootstrap.Modal.Footer>
<ReactBootstrap.Button onClick={this.close}>Close</ReactBootstrap.Button>
</ReactBootstrap.Modal.Footer>
</ReactBootstrap.Modal>
</div>
)
}
});
ReactDOM.render(
<AlbumsPage />,
document.getElementById('albums')
);
You'd have to pass the parent as a prop to the child component.
So in your AlbumList::render, you'd have to do
return (
<Album
key={ album.Id }
title={ album.Title }
getShowModal={ this.getShowModal }
setCurrentAlbum={ this.setCurrentAlbum }
setShowModal={ this.setShowModal }
parent={this}
>
</Album>
);
But this will create a huge overhead once you start passing states to many different components.
A good plugin to solve this would be to use Redux

React - Load Initial List via AJAX

I'm starting to learn react. There's an excellent example in the official docs about loading data initially via AJAX:
var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function (result) {
var lastGist = result[0];
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return (
<div>
{this.state.username}'s last gist is
<a href={this.state.lastGistUrl}>here</a>.
</div>
);
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists" />,
mountNode
);
The code above gets the latest gist of a specific user from GitHub.
What is the best way in React to go about outputting a list of the last 10 gists of the specific user?
How would you modify the code sample above?
var UserGist = React.createClass({
getInitialState: function() {
return {
gists: []
};
},
componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function (result) {
this.setState({
gists: result
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function() {
return <div>
{this.state.gists.map(function(gist){
return <div key={gist.id}>{gist.owner.login}</div>
})}
<div>;
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists" />,
mountNode
);

Unable to render json data in ReactJS components

I am trying to show data from package.json in my ReactJS components. I have seen many answers on SO and tried to implement it. It is neither showing any data nor an error.
This is package.json:
{
"name":"Clark Kent",
"job":"Superman"
}
This is my jsx:
var App = React.createClass({
getInitialState: function(){
return { myData: [] };
},
showResults: function(response){
this.setState({
myData: response
});
},
loadData: function(URL) {
var that = this;
$.ajax({
type: 'GET',
dataType: 'jsonp',
url: URL,
success: function(response){
that.showResults(response);
}
})
},
componentDidMount: function() {
this.loadData("package.json");
},
render: function(){
return(
<div>
<Component1 data={this.state.myData} />
<Component2 data={this.state.myData}/>
</div>
)
}
});
var Component1 = React.createClass({
render: function () {
return(
<div>Name: {this.props.data.name}</div>
)
}
});
var Component2 = React.createClass({
render: function () {
return(
<div>Job: {this.props.data.job}</div>
)
}
});
ReactDOM.render(<App/>, document.getElementById('container'));

load json with reactjs

I'll be very grateful who can help me with this line
I've this:
var Country = React.createClass({
render:function(){
return(
<nav>
<h2>list of country:</h2>
{ this.props.country}
</nav>
)
}
})
var Jugador =React.createClass({
componentWillMount: function(){
var pais;
var self = this;
$.getJSON("https://restcountries.eu/rest/v1/all", function(data){
for(pais in data)
{
console.log(pais, data[pais].name);
return(
<Country key={i} country={self.render(data[pais].name)}> </Country>
)
}
})
},
})
and it does not work, and appear this error
Uncaught Invariant Violation: createClass(...): Class specification must implement a render method.
Your Jugador component needs to implement a render method.
In React each component must have render method, you should implement it. I've refactored your code and now it look like this
var Country = React.createClass({
render: function() {
return <div>
{ this.props.country }
</div>
}
})
var Countries = React.createClass({
getInitialState: function () {
return { countries: [] };
},
componentWillMount: function(){
$.getJSON("https://restcountries.eu/rest/v1/all", function (data) {
this.setState({ countries: data })
}.bind(this))
},
render: function () {
var countries = this.state.countries.map(function (el, i) {
return <Country key={i} country={ el.name } />
}, this);
return <nav>
<h2>list of country:</h2>
<div>{ countries }</div>
</nav>;
}
})
Example

Categories