Im using react and material ui.
This is my component
```
import React from 'react';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import AutoComplete from 'material-ui/AutoComplete';
// the light theme
const lightMuiTheme = getMuiTheme(lightBaseTheme);
// the autocomplete component width
const Preferencestypeahead = {
maxWidth: 600,
position:'relative',
margin:'auto'
}
export default class Preferences extends React.Component {
constructor(props) {
super(props);
this.handleUpdateInput = this.handleUpdateInput.bind();
this.state = {
dataSource: [],
};
}
handleUpdateInput(value){
this.setState({
dataSource: [
value,
value + value,
value + value + value,
],
});
};
render() {
return (
<div>
<MuiThemeProvider muiTheme={lightMuiTheme}>
<section style={Preferencestypeahead}>
<AutoComplete
hintText="Type"
dataSource={this.state.dataSource}
onUpdateInput={this.handleUpdateInput.bind(this)}
floatingLabelText="Search"
fullWidth={true}
/>
</section>
</MuiThemeProvider>
</div>
)
}
}
I keep getting setState is not defined when I type anything inside the autocomplete. Where could I be going wrong? I have also faced this problem when I tried to import the tabs as well
You need to bind to "this"
This line is the problem:
this.handleUpdateInput = this.handleUpdateInput.bind();
Change it to:
this.handleUpdateInput = this.handleUpdateInput.bind(this);
Since you are already using ES6 you could just do
...
onUpdateInput={(val) => this.handleUpdateInput(val)}
...
then you don't need to do this --> this.handleUpdateInput = this.handleUpdateInput.bind(this); in your constructor
Related
I have custom component Slider for Formio. Function attachReact() is attaching my custom component inside element provided by Formio. After attaching is done I am supposed to get an instance for that component from ReactDOM.render() returned right away but I am not. Later that instance is used by Formio to change field values which I need.
How can I make sure I get an instance from ReactDOM returned right away? I realise that feature will be removed in future from React but I still need it while Formio is using it.
import { ReactComponent } from "#formio/react";
import React from "react";
import ReactDOM from "react-dom";
import settingsForm from "./Slider.settingsForm";
class SliderCustomComp extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
};
}
setValue = (v) => {
this.setState({ value: v }, () => this.props.onChange(this.state.value));
};
render() {
return (
<div className="w-full" id="custcomp">
<input
className="w-full focus:outline-none"
type="range"
min={this.props.component.minRange}
max={this.props.component.maxRange}
value={this.state.value}
onChange={(e) => {
this.setValue(e.target.value);
}}
/>
<span>{this.state.value}</span>
</div>
);
}
}
export default class Slider extends ReactComponent {
constructor(component, options, data) {
super(component, options, data);
}
static schema() {
return ReactComponent.schema({
type: "sliderCustomComp",
label: "Default Label",
});
}
static editForm = settingsForm;
attachReact(element) {
console.log(element);
const instance = ReactDOM.render(
<SliderCustomComp
component={this.component} // These are the component settings if you want to use them to render the component.
value={this.dataValue} // The starting value of the component.
onChange={this.updateValue} // The onChange event to call when the value changes.}
/>,
element
);
console.log("instance in attachReact", instance);
return instance;
}
}
Use prop ref to get the instance:
const instanceRef = React.createRef();
ReactDOM.render(
<SliderCustomComp
ref={instanceRef}
component={this.component} // These are the component settings if you want to use them to render the component.
value={this.dataValue} // The starting value of the component.
onChange={this.updateValue} // The onChange event to call when the value changes.}
/>,
element
);
const instance = instanceRef.current;
I am trying to update state in react native component.
But its getting errors, Could someone help me.
I'm using react-native-cli verions: 2.0.1
react-native verions: 0.55.4
Here is my code:
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
state = {
isDone: false
};
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
onPress={this.onAction}
/>
</View>
)
}
}
export default ToggleButton;
You have three different solutions.
Bind your function in the constructor.
Use the experimental public class fields syntax.
Pass a lambda to executing your function.
The problem is that you're loosing the reference to this, because the function is not executed in the original context, so this.setState is not a function, but a undefined.
In this page there are examples for all of the approaches: https://reactjs.org/docs/handling-events.html
Change
onPress={this.onAction}
to
onPress={this.onAction.bind(this)}
Check: this
Below is the solution
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
// Add state in constructor like this
constructor(props){
super(props);
this.state = {
isDone: false
};
}
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
// Add function with onPress
onPress={() => this.onAction}
/>
</View>
)
}
}
export default ToggleButton;
I've followed the docs on installing the inline and static toolbar plugins, but they seems to be nonexistent.
I'm using the Create React App CLI.
The component:
import React from 'react';
import {EditorState} from 'draft-js';
import Editor from 'draft-js-plugins-editor';
import createInlineToolbarPlugin from 'draft-js-inline-toolbar-plugin';
import createToolbarPlugin from 'draft-js-static-toolbar-plugin';
import 'draft-js/dist/Draft.css';
import 'draft-js-inline-toolbar-plugin/lib/plugin.css';
import 'draft-js-static-toolbar-plugin/lib/plugin.css';
const inlineToolbarPlugin = createInlineToolbarPlugin({
//I read somewhere that this plug-in needs this structure passed to it,
//but the example in the docs did not use it, and they are undefined anyway
// structure: [
// BoldButton,
// ItalicButton,
// UnderlineButton,
// CodeButton,
// Separator,
// ],
});
const toolbarPlugin = createToolbarPlugin();
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};
this.onChange = (editorState) => this.setState({editorState});
}
render() {
return (
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={[inlineToolbarPlugin, toolbarPlugin]}
/>
);
}
}
export default TextEditor;
That component is then passed to another component that just renders the editor and does nothing else.
I must be missing something, or not giving the plugins what they need, I just don't know what. I'm guessing the code I have is insufficient to start adding plugins in the first place?
You can define custom buttons to perform the desired operations like below:
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={[inlineToolbarPlugin, toolbarPlugin]}
/>
<button onClick={this._onBoldClick.bind(this)}>Bold</button> //add button to make bold
And now you can write a code to make bold in _onBoldClick method as follows:
_onBoldClick() {
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
}
You can take reference from the docs.
You need to import the buttons before you can create the toolbar
import {
ItalicButton,
BoldButton,
UnderlineButton,
CodeButton
} from "draft-js-buttons";
Also, you need to include the toolbar in your render function
const { Toolbar } = inlineToolbarPlugin;
render() {
return (
<div>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={[inlineToolbarPlugin, toolbarPlugin]}
/>
<Toolbar />
</div>
);
I have the following code in a jsx file and I get error:
Uncaught ReferenceError: AutoComplete is not defined
From what I see it should be working ok, Code:
import React, {Component} from 'react';
import { Autocomplete } from 'material-ui';
class MaterialUIAutocomplete extends Component {
constructor(props) {
super(props);
this.onUpdateInput = this.onUpdateInput.bind(this);
this.state = {
dataSource : [],
inputValue : ''
}
}
onUpdateInput(inputValue) {
}
render() {
return <AutoComplete
dataSource = {this.state.dataSource}
onUpdateInput = {this.onUpdateInput} />
}
}
export default MaterialUIAutocomplete;
It's a typo, you are importing Autocomplete and using AutoComplete.
Use these ways to import AutoComplete:
import { AutoComplete } from 'material-ui';
Or
import AutoComplete from 'material-ui/AutoComplete';
Update:
To render material-ui component we need to add the default theme and styling, include these lines in your component, like this:
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
const muiTheme = getMuiTheme({});
Then render the AutoComplete inside MuiThemeProvider:
render() {
return <MuiThemeProvider muiTheme={muiTheme}>
<AutoComplete
dataSource = {this.state.dataSource}
onUpdateInput = {this.onUpdateInput} />
</MuiThemeProvider>
}
Use this:
import React, {Component} from 'react';
import AutoComplete from 'material-ui/AutoComplete';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
const muiTheme = getMuiTheme({});
class MaterialUIAutocomplete extends Component {
constructor(props) {
super(props);
this.state = {
dataSource : [],
inputValue : ''
}
this.onUpdateInput = this.onUpdateInput.bind(this);
}
onUpdateInput(inputValue) {
}
render() {
return <MuiThemeProvider muiTheme={muiTheme}>
<AutoComplete
dataSource = {this.state.dataSource}
onUpdateInput = {this.onUpdateInput} />
</MuiThemeProvider>
}
}
export default MaterialUIAutocomplete;
Note: MuiThemeProvider is not required to include inside each component, you can use this in main page and then you can use any material-ui component inside any component.
this looks like a migration issue to me - you want to use the material-ui 0.x AutoComplete, but you have installed the new material-ui v1.x.
as such, you need to follow the Migration steps and in order to use any v0.x component, put this wherever you create/declare your themes:
<MuiThemeProvider theme={theme}>
<V0MuiThemeProvider muiTheme={themeV0}>
{/*Components*/}
</V0MuiThemeProvider>
Because the new 1.5 theme is available via props, the old one through context, you need to include both for AutoComplete to have reference to the old theme. I wouldn't do this unless you really need something from the old library, such as the AutoComplete widget.
https://material-ui.com/guides/migration-v0x/
I am trying to implement this carousel using material-ui and react-swipeable-views.
I have a carousel item that looks like this:
import React, {Component, PropTypes} from 'react'
export default class CarouselItem extends Component {
static contextTypes = {
muiTheme: PropTypes.object.isRequired
}
static defaultProps = {
href:'#'
}
constructor(props) {
super(props)
}
render() {
const carouselItemStyle = {
width:'100%',
height:'100%',
minHeight:'400px',
position:'absolute',
top:0,
left:0,
zIndex:-1,
opacity:1,
display:'block'
}
const {prepareStyles} = this.context.muiTheme
const {href,image} = this.props
debugger
return (<a href={href} style={prepareStyles(carouselItemStyle)}>
<img src={image}/>
</a>
)
}
}
I have a Carousel component that looks like this:
import React, {Component, PropTypes} from 'react'
import {v4} from 'node-uuid'
import CarouselItem from './CarouselItem'
import autoPlay from 'react-swipeable-views/lib/autoPlay'
import SwipeableViews from 'react-swipeable-views'
const AutoplaySwipeableViews = autoPlay(SwipeableViews)
export default class Carousel extends Component {
static contextTypes = {
muiTheme: PropTypes.object.isRequired
}
static propTypes = {
items:PropTypes.arrayOf(PropTypes.string),
autoplay:PropTypes.bool
}
static defaultProps = {
autoplay:false
}
constructor(props) {
super(props)
}
render() {
const carousel = {
overflow:'hidden',
position:'relative',
width:'100%',
perspective:'500px',
transformStyle:'preserve-3d',
transformOrigin:'0% 50%'
}
const carouselSlider = {
top:0,
left:0,
height:0
}
const {style:customStyles} = this.props
const style = Object.assign(
carousel,
carouselSlider,
customStyles
)
const {prepareStyles} = this.context.muiTheme
const SwipeImplementation = this.props.autoplay?AutoplaySwipeableViews:SwipeableViews
debugger
const carouselItems = this.props.items.map(function(item){
debugger
return <CarouselItem key={v4()} href="#" image={item}/>
})
return (<div style={prepareStyles(style)}>
<SwipeImplementation>
{carouselItems}
</SwipeImplementation>
</div>
)
}
}
I use the Carousel like this:
const items = [
'http://estruct.com.au/wp-content/uploads/2014/10/old-gccc-logo.png',
'http://www.activehealthycommunities.com.au/wp-content/uploads/2014/07/City-of_Gold-Coast_stacked_CMYK-01.jpg'
]
return (
<Carousel items={items} autoplay={true} />
)
I find that the carousel items do not appear, when I look in the developer tools, I find that transitions are happening but I do not see the items.
I have created a webpackbin with the code
I get an error in the bin that I do not have in my dev environment.
UPDATE:
If I remove the style for the a tag and change it to a div within CarouselItem:
//style={prepareStyles(carouselItemStyle)}
return (<div><img src={image}/></div>)
The images are displayed but are not full width. I notice that the transform css as well as height are determined using jQuery. How can we establish proper styling for the CarouselItem.
I think the problem is with your helloWorld.js. You're not creating the component correctly. Switching it to this is rendering the images for me.
export default class HelloWorld extends React.Component {
render() {
const items = [
'http://estruct.com.au/wp-content/uploads/2014/10/old-gccc-logo.png',
'http://www.activehealthycommunities.com.au/wp-content/uploads/2014/07/City-of_Gold-Coast_stacked_CMYK-01.jpg'
]
return (
<MuiThemeProvider>
<Carousel items={items} autoplay={true}/>
</MuiThemeProvider>
);
}
}