Using material-ui with ecmascript6 - reactjs

I jus find material-ui and I'm trying to add some components in the following way
import React from 'react';
import mui from 'material-ui';
import injectTapEventPlugin from 'react-tap-event-plugin';
import PropertiesList from './../components/propertylist.jsx';
import Filters from './../components/filter.jsx';
import Properties from './../models/PropertiesModel.js';
import Toolbar from './../components/toolbar.jsx';
var AppBar = mui.AppBar;
var IconButton = mui.IconButton;
var NavigationClose = mui.NavigationClose;
var ThemeManager = new mui.Styles.ThemeManager();
var FlatButton = mui.FlatButton;
injectTapEventPlugin();
class TransProperties extends React.Component {
constructor(props){
super(props);
}
render() {
return <div className="row">
<div className="col-lg-9">
<AppBar
title="Title"
iconElementLeft={<IconButton><NavigationClose /></IconButton>}
iconElementRight={<FlatButton label="Save" />} />
<PropertiesList url="/properties.json"/>
</div>
<div className="col-lg-3">
<Filters/>
</div>
</div>;
}
handleTouchTap() {
alert("oh hi");
}
}
export default TransProperties
but I get an error Uncaught TypeError: Cannot read property 'spacing' of undefined
which refers to
getStyles: function getStyles() {
var spacing = this.context.muiTheme.spacing;...}
What did I missed?

You're likely missing the contextType on your component, which makes muiTheme available.
Your component should look something like this:
class ExampleComponent extends React.Component {
getStyles() {
...
let spacing = this.context.muiTheme.spacing;
...
}
render() {
return (
<div style={this.getStyles()} />
);
}
}
// Don't forget this little nugget
ExampleComponent.contextTypes = {
muiTheme: React.PropTypes.object
}

Related

How do I change the attributes of a dependencies?

So I am trying to learn how to use the npm library, and I found this carousel. I implemented it into my project, but I am unsure about how to change the attributes. Here is the doc: https://www.npmjs.com/package/react-responsive-carousel
and here is my current code:
import React, { Component } from 'react';
import "react-responsive-carousel/lib/styles/carousel.min.css";
import { Carousel } from 'react-responsive-carousel';
import Project1 from './Project1'
import Project2 from './Project2'
class Projects extends Component {
constructor(props){
super(props)
this.state = {
showArrows: 'false',
showIndicators: 'false'
}
}
render() {
const styles = {
display: 'none'
}
return (
<Carousel>
<div>
<Project1 />
</div>
<div>
<img style = {styles}src="http://lorempixel.com/output/cats-q-c-640-480-1.jpg" />
<Project2 />
</div>
</Carousel>
);
}
};
export default Projects
You can do it as you will do for normal components.
<Carousel showArrows={false} showIndicators={false}>
Refer for demos.

imported component is not displayed

i've a component that i import, but its not displayed on the page.
this is my app.js file. i imported the <player/>component but it is not getting displayed properly on the browser.
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import { player } from "./player";
class App extends Component {
render() {
return (
<div className="App">
<div>
<player />
</div>
</div>
);
}
}
export default App;
this is the contents of the player.js
import React from "react";
import { Button } from "evergreen-ui";
export default class player extends React.Component {
constructor(...args) {
super(...args);
this.state = {
shoot: 0
};
}
shoot() {
this.setState.shoot = Math.floor(Math.random() * Math.floor(3));
}
render() {
return (
<div>
<h1>hello there</h1>
<h1>{this.state.shoot}</h1>
<Button onClick={() => this.shoot}>Shoot another
value</Button>
</div>
);
}
}
In your code, you've exported your player component as a default export
export default class player extemds React.Component
But in your import of it in the other file, you're importing it as a named export
import { player } from "./player";
Try importing it without the curly braces as you would with a default export
import player from "./player";
You are doing two mistakes:
1. Importing the component in the wrong way
2. Rendering the component in the wrong way
Solution
The component should be imported without the curly braces
The react component "player" is supposed to start with capital letters i.e. it should be renamed as Player
Below is the working code I have tried in my local machine. It only modifies App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import Player from "./player"; // imported without curly braces and with capital first letter
class App extends Component {
render() {
return (
<div className="App">
<div>
<Player /> {/* Rendering the correct way */}
</div>
</div>
);
}
}
export default App;
Sidenote
In player.js, you are setting the state in the wrong fashion, it won't work because:
setState is a method and not a object
this is not binded with method shoot. It will throw error something like "cannot read this of undefined" or something
Modify your player.js as following:
import React from "react";
import { Button } from "evergreen-ui";
export default class player extends React.Component {
constructor(...args) {
super(...args);
this.state = {
shoot: 0
};
}
shoot = ()=>{
this.setState({
shoot: Math.floor(Math.random() * Math.floor(3)),
});
}
render() {
return (
<div>
<h1>hello there</h1>
<h1>{this.state.shoot}</h1>
<Button onClick={() => this.shoot()}>Shoot another
value</Button>
</div>
);
}
}
You have two main issues:
1) You export as default and then your import is wrong.
If you export as:
export default class player extemds React.Component
Then you need to import as:
import player from "./player";
2) Components must start uppercase, otherwise React thinks that they are simple HTML tags and not components.
So you must change player to Player everywhere

React and d3-graphviz

I'm trying to render a graphviz graph from a dotfile in my React Component. I keep running into errors I don't understand. If anyone could shed some light I would be grateful.
import React from 'react';
import dotSrc from '../../assets/visualize_dotfile.dot';
import Viz from 'viz.js';
import * as d3 from 'd3'
import * as d3Graphviz from 'd3-graphviz';
class Visualization extends React.Component {
setGraph() {
console.log('DOT source =', dotSrc);
const dotSrcLines = dotSrc.split('\n');
d3.select(".graph").graphviz().renderDot(dotSrc);
}
render(){
return (
<div className="graph">
{this.setGraph}
</div>
)
}
}
export default Visualization;
I've also tried:
import React, { Component } from 'react';
import { render } from 'react-dom';
import dotSrc from '../../assets/visualize_dotfile.dot';
import Viz from 'viz.js';
import HTMLReactParser from 'react-html-parser';
const graph = Viz({ files: [ { path: dotSrc } ] });
class Visualization extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div>
<div>
{HTMLReactParser(graph)}
</div>
</div>
);
}
}
render(<Visualization />, document.getElementById('root'));
To no avail. Neither Viz nor GraphViz wants to read my dotfile though I'm not sure I'm using the correct syntax either.
Thank you in advance.
It's not exactly clear what you want to do and what errors you are getting.
This code at least generates a graph from a static string when the button is clicked:
import React, { Component } from 'react';
import * as d3 from 'd3'
import * as d3Graphviz from 'd3-graphviz';
var dotSrc = 'digraph {a -> b}';
class App extends Component {
setGraph() {
console.log('DOT source =', dotSrc);
d3.select(".graph").graphviz().renderDot(dotSrc);
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to magjac's React hack</h1>
</header>
<script src="https://unpkg.com/viz.js#1.8.0/viz.js" type="javascript/worker"></script>
<div className="graph">
</div>
<button className="square" onClick={() => this.setGraph()}>
{'Click me'}
</button>
</div>
);
}
}
export default App;

How can you render a react component using dynamic name?

Here's what I've tried and all it does is insert html with the theme value as the tag. It doesn't create an actual React Component.
!!! Let's assume the theme name is 'rounded'
renderTemplate(){
const store = JSON.parse(localStorage.getItem('store'));
const template = this.state.product.template;
const Theme = `${template.charAt(0).toUpperCase()}${template.slice(1)}`;
return <Theme store={this.props.store} product={this.state.product} />;
}
render(){
return (
<div>
{ _.isEmpty(this.state.product) ?
'LOADING'
:
this.renderTemplate()
}
</div>
)
}
Also, I read in another question that someone mentioned something about it can't be wrapped in an html element so I also tried this unsuccessfully:
render(){
return (
_.isEmpty(this.state.product) ?
<div>LOADING</div>
:
this.renderTemplate()
)
}
Both cases just render html elements like (from console inspector):
<div class="row">
<rounded store="XXXXX" product="XXXXX"></rounded>
<rounded store="XXXXX" product="XXXXX"></rounded>
<rounded store="XXXXX" product="XXXXX"></rounded>
</div>
In React Inspector:
<div class="row">
<Rounded store="XXXXX" product="XXXXX"></Rounded>
<Rounded store="XXXXX" product="XXXXX"></Rounded>
<Rounded store="XXXXX" product="XXXXX"></Rounded>
</div>
And if it helps the React Console shows each of the divs children as:
$$typeof: Symbol(react.element)
Empty object
EDIT !!!!
Import Rounded from ‘./Themes/Rounded’;
In case it is missed here... what I need to accomplish is rendering an actual react component named <Rounded />
EDIT 2 !!!!
Here is the complete code (minus anything irrelevant):
import React from 'react';
import ReactDOM from 'react-dom';
// IMPORT THEMES
import {
Rounded,
Square,
[Other themes here]
} from './Themes';
class MyClass extends React.Component {
constructor(props){
super(props);
this.state = {
product: {}
};
}
renderTemplate(){
const template = this.state.product.template;
const Theme = `${template.charAt(0).toUpperCase()}${template.slice(1)}`;
return <Theme product={this.state.product} />;
}
render(){
return (
_.isEmpty(this.state.product) ?
<div>LOADING</div>
:
this.renderTemplate()
)
}
}
export default MyClass;
Here's how you do it!
import React from 'react';
import ReactDOM from 'react-dom';
// IMPORT THEMES
import * as Themes from './Themes';
class MyClass extends React.Component {
constructor(props){
super(props);
this.state = {
product: {}
};
}
renderTemplate(){
const template = this.state.product.template;
const Theme = Themes[template.charAt(0).toUpperCase() + template.slice(1)];
return <Theme product={this.state.product} />;
}
render(){
return (
_.isEmpty(this.state.product) ?
<div>LOADING</div>
:
this.renderTemplate()
)
}
}
export default MyClass;
Notice the import * as which automatically sticks all classes in an array for you. An array of functions I should mention. So now Themes[] is a direct reference to a function and not just a string.

I cannot use material-ui components after update to material-ui#0.15.0-beta.1

I got this message in my console:
Failed Context Types: Required context muiTheme was not specified in
AppBar
AppBar.js:158 Uncaught TypeError: Cannot read property 'prepareStyles'
of undefined
I just have an AppBar in my Component
I think it should work but...
here my very simple code:
import React from 'react';
import {AppBar} from 'material-ui';
export class MyComponent extends React.Component {
render() {
return (
<div>
<AppBar
title="Title"
/>
</div>
);
}
}
thanks for helping...
With material-ui#0.15.0.beta-1 a few things were changed.
You can have a look on the link below for more details.
https://github.com/callemall/material-ui/blob/master/CHANGELOG.md
Therefore with those changes your code becomes:
import React from 'react';
import AppBar from 'material-ui/AppBar';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export class MyComponent extends React.Component {
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render() {
return (
<div>
<AppBar
title="Title"
/>
</div>
);
}
}
MyComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
now in the 0.15.0 you can use muiThemeProvider:
...
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import MyAwesomeReactComponent from './MyAwesomeReactComponent';
const App = () => (
<MuiThemeProvider muiTheme={getMuiTheme()}>
<MyAwesomeReactComponent />
</MuiThemeProvider>
)
...
So you do not have to provide context to childrens manualy.
More info in documentation.
Import MuiThemeProvider and then wrap the material-ui component AppBar with MuiThemeProvider.
import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import './App.css';
class App extends Component {
render() {
return (
<MuiThemeProvider>
<div>
<AppBar title = "Title" />
</div>
</MuiThemeProvider>
);
}
}
export default App;

Resources