What is the meaning of the three points Operator in Javascript - javascript

i see rubix code
http://wrapbootstrap.com/preview/WB09498FH (site right up demo click)
it is code in react component
javascript
//react ES6
var InboxItem = React.createClass({
mixins: [State, Navigation],
statics: {
ID: 0,
resetID: function() {
InboxItem.ID = 0;
},
getID: function() {
return ++InboxItem.ID;
}
},
handleClick: function(e) {
e.preventDefault();
e.stopPropagation();
this.transitionTo('/app/mailbox/mail');
},
render: function() {
var classes = classNames({
'inbox-item': true,
'unread': this.props.unread
});
var props = {
href: '/app/mailbox/mail',
onClick: this.handleClick,
...this.props,
className: classes
};
return (
<a {...props}>
<div className='inbox-avatar'>
<img src={this.props.src} width='40' height='40' className={this.props.imgClass + ' hidden-xs'} />
<div className='inbox-avatar-name'>
<div className='fg-darkgrayishblue75'>{this.props.name}</div>
<div><small><Badge className={this.props.labelClass} style={{marginRight: 5, display: this.props.labelValue ? 'inline':'none'}}>{this.props.labelValue}</Badge><span>{this.props.description}</span></small></div>
</div>
<div className='inbox-date hidden-sm hidden-xs fg-darkgray40 text-right'>
<div style={{position: 'relative', top: 5}}>{this.props.date}</div>
<div style={{position: 'relative', top: -5}}><small>#{InboxItem.getID()}</small></div>
</div>
</div>
</a>
);
}
});
onClick next line code
...this.props
and
return next line code
a {...props}
what is this "..." ?

As #zerkms mentioned in the comments; it is the Object Rest/Spread Properties syntax in the ECMAScript 2016 (ES7) Proposal, also mentioned in the React docs.
The code you see
var props = {
href: '/app/mailbox/mail',
onClick: this.handleClick,
...this.props,
className: classes
};
gets evaluated to the following, where the props object properties get extended onto the new props object:
var props = {
href: '/app/mailbox/mail',
onClick: this.handleClick,
src: 'https://example.com',
name: 'myName',
labelClass: 'myLabelClass',
labelValue: 'mylabelValue',
className: classes
};

Related

React onClick event does not fire setState

I am trying to build an image gallery in React.js, everything went smoothly until now.In gallery I am creating Thumbnail objects - on click this will fire "mini gallery" with all pictures from particular project and description for project. However to get back to main gallery I am creating "CLOSE" button within "mini gallery" with an attached handler.Thumbnail click works, however Close Button does not. Please see code attached below.I will be very grateful for any help!
This is Main Gallery:
import React from 'react';
import Thumbnail from '../components/Thumbnail';
export default class Drawings extends React.Component {
render () {
const linkPrefix = "./life/";
const imageS = ".800.jpg";
const imageL = ".jpg";
const lifePics = [
{
name: "One",
filename: [
"lifedrawing1",
],
descr: "one",
},
{
name: "Two",
filename: [
"lifedrawing2",
"lifedrawing2ed",
"lifedrawing2ed2",
],
descr: "two",
},
{
name: "Three",
filename: [
"lifedrawing3",
],
descr: "three",
},
]
return (
<div id="Drawings" className="container row around wrap">
{lifePics.map(
(picture, i) =>
<Thumbnail
key={i}
linkPrefix={linkPrefix}
filename={picture.filename}
imageS={imageS}
imageL={imageL}
/>
)}
</div>
);
}
}
This is each Thumbnail:
import React from 'react';
export default class Thumbnail extends React.Component {
constructor(props) {
super(props);
this.state = {
viewerDisplay: "hidden",
};
}
thumbnailClick(event) {
this.setState({
viewerDisplay: "visible",
});
}
closeViewer(event) {
this.setState({
viewerDisplay: "hidden",
});
}
render () {
const thumbnailStyle = {
width: '45%',
height: '300px',
backgroundImage: 'url('+this.props.linkPrefix + this.props.filename[0]+this.props.imageS+')',
backgroundSize: 'cover',
marginBottom: '10px',
cursor: 'pointer',
};
var viewerStyle = {
position: "absolute",
top: "300px",
right: "50px",
bottom: "10px",
left: "50px",
visibility: this.state.viewerDisplay,
background: "black",
cursor: "auto",
};
const viewerColStyle = {
width: "50%",
height: "100%",
}
return (
<div
className="thumbnail container col between"
style={thumbnailStyle}
onClick={this.thumbnailClick.bind(this)}
>
<div
id="Viewer"
className="viewer container row between"
style={viewerStyle}
>
<div
id="PicList"
className="container col around"
style={viewerColStyle}
>
Thumbnails
{//map function for thumbnails of particular gallery
}
</div>
<div
id="ProjectDescr"
className="container col around"
style={viewerColStyle}
>
Project Descr
</div>
<button
onClick={this.closeViewer.bind(this)}
>CLOSE</button>
</div>
</div>
);
}
}
you should add event.stopPropagation() to the closeViewer function to prevent propagation of the click event to Thumbnail div element
closeViewer(event) {
event.stopPropagation();
this.setState({
viewerDisplay: "hidden",
});
}
Here is an example without stopPropagation
<body>
<div onclick="clickDiv()">
<button onclick="clickButton()">Test</button>
</div>
<script>
function clickButton() {
alert('clickButton');
}
function clickDiv() {
alert('clickDiv');
}
</script>
</body>
Here is an example with stopPropagation
<body>
<div onclick="clickDiv()">
<button onclick="clickButton(event)">Test</button>
</div>
<script>
function clickButton(e) {
e.stopPropagation();
alert('clickButton');
}
function clickDiv() {
alert('clickDiv');
}
</script>
</body>
You should bind your click handler in the constructor or make it an arrow function in order to pass context:
thumbnailClick = (event) => {
this.setState({
viewerDisplay: "visible",
});
}

onMouseLeave event is not triggering

This is nav component. This nav component rendered at run time. Text should be visible when mouse will enter to div with ref "text_nav" and text should hide when mouse will leave div with ref "text_nav".
onMouseLeave is not working
var React = require('React');
var $ = require('jquery');
var Nav = React.createClass({
getInitialState: function() {
return {
items: []
}
},
componentWillMount: function() {
var _this = this;
this.serverRequest =
$.post("/nav", {}, function(result) {
_this.setState({
items: result.data
});
})
},
onMouseEnter: function() {
this.refs.text_navigator.style = {display: true}
},
onMouseLeave: function() {
this.refs.text_navigator.style = {display: 'none'}
},
render: function() {
var text = this.state.items.map(function(data, index) {
var icon = "text_" + data.sname;
return (
<div id={icon} key={index} className="text_nav_item">
<p>
<span><a href={data.url}>{data.title} </a></span>
</p>
</div>
);
});
return (
<div id="nav" className="fixed" style={{zIndex: 1018}} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<div id="text_nav" ref="text_navigator" style={{display: 'none'}} >
<div id="text_nav_content">
{item_text}
</div>
</div>
</div>
)
}
})
First off, the ref is text_nav in your render method, not text_navigator as you're using in onMouseEnter and onMouseLeave. But the main issue is that you can't set the display style the way you're trying to do, as
this.refs.text_navigator.style = {display: true}
The most common approach to take is to set a boolean in state, perhaps called displayTextNavigator. In getInitialState, set it to false, and then your onMouseEnter and onMouseLeave functions can be:
onMouseEnter: function() {
this.setState({ displayTextNavigator: true})
},
onMouseLeave: function() {
this.setState({ displayTextNavigator: false})
},
Now in your render method, you can change your wrapping div to look like this:
<div id="text_nav" ref="text_nav" style={{display: this.state.displayTextNavigator ? 'block': 'none'}} >
You can pull that ternary operator out to earlier in the render method if you'd like it be more readable.

how to create slider effect on rendering new elements from state in reactjs?

When switching data by selecting slice from an array, putting it into state and rendering by setInterval, I try to create a slider effect by clicking up and down arrows:
UPDATE START
I was finally able to create slider using technique from this codepen:
http://codepen.io/sergiodxa/pen/aOYdeN
UPDATE END
var MainContainer = React.createClass({
getInitialState: function () {
return {
position: 0,
max_elements: 3,
data: [],
source: Array.prototype.slice.call([1, 2, 3, 4, 5, 6, 7]).reverse()
}
},
componentDidMount: function () {
setInterval(this.updateState, 10);
},
arrowUp: function () {
if (this.state.position > 0) {
this.state.position--;
this.updateState();
}
},
arrowDown: function () {
if (this.state.source.length - this.state.position > this.state.max_elements) {
this.state.position++;
this.updateState();
}
},
updateState: function () {
data = this.state.source.slice(this.state.position, this.state.position + this.state.max_elements)
this.setState({data: data});
console.log(this.state.data);
},
render: function () {
var Items = this.state.data.map(function (item, i) {
return (
<div key={i}>
<SimpleItem message={item} active={i == 0 ? true : false}/>
</div>
);
}, this);
return (
<div>
{Items}
<ArrowUp onClick={this.arrowUp}/>
<ArrowDown onClick={this.arrowDown}/>
</div>
);
}
});
var ArrowUp = React.createClass({
render: function () {
return (
<a href="#" className="glyphicon glyphicon-arrow-up" onClick={this.props.onClick}>
</a>
);
}
});
var ArrowDown = React.createClass({
render: function () {
return (
<a href="#" className="glyphicon glyphicon-arrow-down" onClick={this.props.onClick}>
</a>
);
}
});
var SimpleItem = React.createClass({
render: function () {
var className = "well well-lg"
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
className = this.props.active ? className + " active" : className;
return (
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true} transitionAppearTimeout={500}
transitionEnter={false} transitionLeave={false}
>
<div className={className}>
{this.props.message}
</div>
</ReactCSSTransitionGroup>
);
}
});
ReactDOM.render(<MainContainer />, document.getElementById('container'));
The animation is only seen when components render for the first time, re-rendered elements won't animate, for some reason.
My styles are:
.example-appear {
opacity: 0.01;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
I'm not a frontend guy so any hint or link would be much appreciated.
I noticed a couple of things wrong. This first is in you arrowUp and down functions. State always needs to be set using the setState() function. From the docs:
NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.
The second thing is that the children of ReactTransition group must have a unique key. When this key changes that is what tells react transition group to animate.
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true} transitionAppearTimeout={500}
transitionEnter={false} transitionLeave={false}
>
{*/ This div needs a key. When the key changes react transition group animates. /*}
<div key={this.state.currentItem} className={className}>
{this.props.message}
</div>
</ReactCSSTransitionGroup>
In the above example I've set the key to this.state.currentItem your up and down arrow functions would update state.currentItem appropriately, react would re-render the component, react transition group would animate because this.state.currentItem changed.

Render new element onClick in react.js

I'm new to react and am trying to render a new element onClick:
var LoginButton = React.createClass({
..............
..............
clickHandle : function() {
this.rememberMe = {
active: localforage.getItem('rememberMe', function (err, key) {
return key;
})
};
if (this.rememberMe.active == true || this.rememberMe.active == 'checked')
{
document.getElementById('loginForm').submit();
}
else {
React.render(<wantToRemember />, document.getElementById('loginbuttonhere'));
}
return this.rememberMe.active;
},
This is the element that should appear:
var wantToRemember = React.createClass({
getInitialState : function () {
return {
position: 'absolute',
display: 'block',
top: '20px',
width: '100px',
height: '100px'
}
},
render : function () {
return (
<div className="rememberPopup" style={this.state}>
<div className="row">
<div className="staylogin">
<div className="col-md-4">
<label for="checkbox">Angemeldet bleiben</label>
</div>
<div className="col-md-1">
<input type="checkbox" id="checkbox" name="remember" />
</div>
</div>
</div>
</div>
);
}
});
but it doesn't appear, instead react renders this html:
<wanttoremember data-reactid=".1"></wanttoremember>
I'm pretty sure I'm doing some pretty basic stuff wrong, but can't figure out what. Isn't it possible to call different elements like this?
Your react.js component name begins with a lower-case letter, it should start with an upper-case leter: var WantToRemember = React.createClass(...) and React.render(<WantToRemember />,....
The JSX compiler requires for component names to begin with an upper-case letter (see jsx docs on this):
To render a React Component, just create a local variable that starts with an upper-case letter:
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
React.render(myElement, document.getElementById('example'));
You should pass a React element to React.render instead of the tag itself, something like this:
React.render(
React.createElement(wantToRemember)
);

React jsx first tab breaks after switch

Currently constructing an App in reactjs and hit a strange issue. JSX code is below (sorry it's a bit verbose):
var NavigationTab = React.createClass({
onClick: function() {
console.log('NT' + this.props.tab.index);
this.props.onTabClick(this.props.tab.index);
},
render: function(index){
return (
<li>
<a href="#" onClick={this.onClick} className='navigation-tab'> {this.props.tab.title} </a>
</li>
)
}
});
var NavigationPanel = React.createClass({
getInitialState: function() {
return {
};
},
onTabClick: function(tab) {
//console.log(i) ;
this.setState({active : tab});
this.props.showTab(tab);
},
render: function() {
var self = this;
var tabs = this.props.tabs.map(function(item, index){
item.index = index;
return <NavigationTab tab={item} onTabClick={self.onTabClick} />;
});
return (
<div id='navigation-panel' className='col-xs-2'>
<ul className='nav nav-pills nav-stacked'>
{tabs}
</ul>
</div>
);
}
});
var App = React.createClass({
getInitialState: function() {
return {
tabs: [
{title: 'test', ref: 'test', content: <div> test </div>},
{title: 'Dasboard', ref: 'dashboard', content: <div> home </div>},
{title: 'Settings', ref: 'settings', content: <div> settings </div>},
{title: 'Logout', ref: 'logout', content: <div> logout </div>}
],
activeTab: 0};
},
showTab : function(index) {
console.log('AP ' + index);
this.setState({activeTab : index});
},
render: function() {
console.log('AP ' + this.state.activeTab);
console.log('AP ' + this.state.tabs[this.state.activeTab].title);
return (
<div id="container">
<NavigationPanel showTab={this.showTab} tabs={this.state.tabs} />
<div id="content-body">
{this.state.tabs[this.state.activeTab].content} /* [1] */
</div>
</div>
);
}
});
What happens is after changing tabs, the first tab 'test' will no longer display.
If I change the line at /* [1] */ to {this.state.tabs[this.state.activeTab].ref} it works as expected.
Here is a fiddle
In older versions of React, you couldn't reuse component descriptors and needed to recreate them when rendering them multiple times. Your code works fine with React 0.11.

Categories

Resources