I want to exetend Tab component with es6 class like this:
import React from "react";
import {Tab} from "material-ui";
class MyTab extends Tab {
constructor(props){
super(props);
}
render(){
return super.render();
}
}
export default MyTab;
But i get an error:
Uncaught TypeError: Cannot read property 'muiTheme' of undefined
What am I doing wrong?
The correct way to extend an MUI component is using their withStyles() higher-order component Design Approach
import React, { Component } from "react";
import Tab from "#material-ui/core/Tab";
import { withStyles } from "#material-ui/core/styles";
const styles = theme => {
return ({
myTab: {
fontFamily: 'Courier New',
});
}
class MyTab extends Component {
render() {
return (
const {classes, ...other} = this.props
<Tab {...other} className={classes.myTab} label="Home" />
}
}
export default withStyles(styles)(MyTab);
Currently it seems to require a 'getInitialState' function even if you are working in ES6. So just add one (and ignore the errors) for now.
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import LightTheme from 'material-ui/lib/styles/raw-themes/light-raw-theme';
getInitialState() {
return this.state;
}
I also set this state in the constructor ala ES6 React.
this.state = {muiThem : ThemeManager.getMuiTheme(LightThem),};
Related
this is very basic but I'm new to JS and new to React, I need a few pointers on what I'm doing wrong. I have a Slider components I would like to change, and I would like to reflect/store the new value of the Slider in the class state. How should I be writing this?
I get this error:
TypeError: Cannot read properties of undefined (reading 'value')
Code example below:
import React from 'react';
import { Text, View, Button } from 'react-native';
import Slider from '#react-native-community/slider';
import { TextInput } from 'react-native-paper';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value1: 1
};
}
render() {
return(
<View>
<Text>Slider</Text>
<Slider
value={this.state.value1}
onValueChange={(e) => this.setState({value1: e.target.value})}
minimumValue={1}
maximumValue={5}
step={1}/>
</View>
);
}
}
export default App;
there is no mood property in your code, I highly recommend you to work with functional components instead of class components to be able to use hooks and make your code more clean and readable.
for more information check React Functional Components VS Class Components
I revised your code, now it updates the state of value1 whenever the slider moves:
import React from 'react';
import { Text, View, Button } from 'react-native';
import Slider from '#react-native-community/slider';
import { TextInput } from 'react-native-paper';
const App = (props) =>{
const [value1 , setValue1] = React.useState(1)
return(
<View>
<Text>The value is : {value1}</Text>
<Slider
value={value1}
onValueChange={setValue1}
minimumValue={1}
maximumValue={5}
step={1}/>
</View>
);
}
export default App;
demo
No mood property in your code. So it is undefined.
I am learning ReactNative, and now I'm looking into how to organize the files (for now I am going to create a folder for each page, each with an index, functions and styles file). For some reason, though, I am not being able to import information to index.js, can't use the styles or functions, when I open the page, it doesn't return the func method.
I am wondering whether I am using import wrong. Using import { MenuFunctions} from './Menu' has resulted in an error saying nothing was imported, this error no longer appears, but nothing is being returned still.
This is my code, index, Menu and styles are all in the same folder.
index.js
import React from 'react';
import MenuFunctions from './Menu';
import MenuStyles from './styles'
import { Text, View } from 'react-native';
export default class MenuPage extends React.Component {
render(){
return(
<View>
<Text> Text: {MenuFunctions.func} </Text>
</View>
);
}
}
Menu.js
import React from 'react';
export default class MenuFunctions extends React.Component{
constructor(props){
super(props);
}
func = () => {return "Hello, World!"};
}
styles.js
import React from 'react';
import { StyleSheet } from 'react-native';
export default class MenuStyles extends React.Component{
styles = StyleSheet.create({
text: {
color: "red",
}
});
}
Menu.js and styles.js shouldn't be React.Component and you forgot to call to Func method, () is missing.
React.Component is a UI component only which include a render method that returns JSX element.
Your code should look like that:
index.js
import React from 'react';
import MenuFunctions from './Menu';
import MenuStyles from './styles';
import {Text, View} from 'react-native';
export default class MenuPage extends React.Component {
render() {
return (
<View>
<Text> Text: {MenuFunctions.func()} </Text>
</View>
);
}
}
Menu.js
import React from 'react';
class MenuFunctions {
func = () => {
return 'Hello, World!';
};
}
export default new MenuFunctions();
styles.js
import {StyleSheet} from 'react-native';
export default styles = StyleSheet.create({
text: {
color: Colors.red30,
}
});
The problem is that you are trying to import Menu.js using import MenuFunctions from './Menu' when you had to specify the file itself:'./Menu/Menu.js'. (remember to call the function using parentheses class.function())
Also, whenever you export as default you don't have to use curly braces {}
If you are wondering about your project structure, you can use the following as a common structure to create projects. Let's say you have the following
- index.js
- src
- assets
- screens
- MenuScreen
- components
- services
- menu
- index.js //this is Menu.js
- android
- ios
NOTE
Do not extend React.Component if you are not exporting a component.
You need an object to perform the function of the class you created.
Then declare and use the constructor.
index.js
import React from 'react';
import MenuFunctions from './Menu';
import MenuStyles from './styles'
import { Text, View } from 'react-native';
export default class MenuPage extends React.Component {
constructor(props){
super(props);
this.menu = new MenuFunctions()
MemuStyle = new MenuStyles()
}
render(){
return(
<View>
<Text style={MemuStyle.styles.text}> Text: {this.menu.func()}</Text>
</View>
);
}
}
Menu.js
import React from 'react';
export default class MenuFunctions extends React.Component {
func(){
return 'Hello, World!';
}
}
styles.js
import { StyleSheet } from 'react-native';
export default class MenuStyles extends React.Component {
styles = StyleSheet.create({
text: {
color: "red",
}
});
}
NOTE: The features you intend to use do not necessarily have to inherit React.
This is my class:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';
class MyClass extends Component {
constructor(props) {
super(props);
}
get pageTitle() {
const { intl } = this.props;
return intl.formatMessage({id: 'messages_my_class_page_title'});
}
render() {
return (
<div>
Dummy content
</div>
);
}
}
MyClass.propTypes = {
intl: intlShape.isRequired
}
export default injectIntl(MyClass);
My page title appears when I put in a random text and don't use react-intl injectIntl function.
I have 'react-intl' working fine for all other cases. Even for static properties using 'hoist-non-react-statics' library.
I am stumbled upon this one.
Edit 1:
I can fix it using
<FormattedMessage id="messages_my_class_page_title"/>
But I want to know how to use injectIntl way.
I'm writing an example app over here to get my head around React but one of my simpler components is throwing an error that I can't seem to track.
Error: Element type is invalid: expected a string (for built-in
components) or a class/function (for composite components) but got:
undefined. You likely forgot to export your component from the file
it's defined in. Check the render method of ContactListItem.
Here's the code for the ContactListItem component.
import React, { Component } from 'react';
import { ListGroupItem } from 'react-bootstrap';
import { Link } from 'react-router';
class ContactListItem extends Component {
render() {
const { contact } = this.props;
return (
<ListGroupItem>
<Link to={'/contact/${contact.id'}>
<h4>{contact.name}</h4>
</Link>
</ListGroupItem>
);
}
}
export default ContactListItem;
It's a pretty simple class. Nothing sticks out to me as problematic. For completion's sake, here's the parent component.
import React, { Component } from 'react';
import { ListGroup } from 'react-bootstrap';
import ContactActions from '../actions/ContactActions';
import ContactStore from '../stores/ContactStore';
import ContactListItem from './ContactListItem';
function getContactListItem(contact) {
return (
<ContactListItem key={contact.id} contact={contact} />
);
}
class ContactsComponent extends Component {
constructor() {
super();
this.state = {
contacts: []
}
this.onChange = this.onChange.bind(this);
}
componentWillMount() {
ContactStore.addChangeListener(this.onChange);
}
componentDidMount() {
ContactActions.receiveContacts()
}
componentWillUnmount() {
ContactStore.removeChangeListener(this.onChange);
}
onChange() {
this.setState({
contacts: ContactStore.getContacts()
});
}
render() {
let contactListItems;
if ( this.state.contacts ) {
contactListItems = this.state.contacts.map(contact => getContactListItem(contact));
}
return (
<div>
<ListGroup>
{contactListItems}
</ListGroup>
</div>
);
}
}
export default ContactsComponent;
You get the error in ContactListItem#render() because Link is undefined. As of React Router v4, <Link /> is no longer a part of the react-router, but a part of the react-router-dom package. Changing this should fix your problem:
import { Link } from 'react-router-dom';
As per documentation,
use
import { Link } from 'react-router-dom';`
unlike react-router which used to work earlier.
But react-router-dom comes with:
HashRouter
BrowserRouter
MemoryRouter
Prompt
NavLink
StaticRouter, etc.
You might benefit from tree-shaking a lot, on using
import Link from 'react-router-dom/Link';
if all the above stuffs are not needed in your app.
I need advice on how to pass a Reactjs prop from a component to my app when it's loaded. I'm able to pass the value when my props are in app.js but how do I handle the prop when loading from a separate component?
Here's what's working so far in app.js:
import React, { PropTypes, Component } from 'react';
import { Grid, Nav, Navbar, NavItem, Jumbotron } from 'react-bootstrap';
import { Link } from 'react-router';
import { LinkContainer, IndexLinkContainer } from 'react-router-bootstrap';
function HeaderTitle(props) {
return <h1>{props.name}</h1>;
}
const headerTitle = <HeaderTitle name="About Page" />;
class App extends React.Component {
constructor(props) {
super(props);
}
render() { ...
<p>{headerTitle.props.name}</p>
Parent to Child
If you want to pass all the props through:
render() {
return (
<div>
<HeaderTitle {...this.props} />
</div>
);
}
Or if just some:
render() {
return (
<div>
<HeaderTitle name={this.props.name} />
</div>
);
}
Child to Parent
If you mean the other way round, you need to use a callback
// app
render() {
return (
<div>
<HeaderTitle onGetName={(name) => this.setState({childName: name})} />
<p>{this.state.childName}</p>
</div>
);
}
// headertitle
componentDidMount() {
// maybe some async call or something
axios
.get('/api/say-my-name')
.then(response => this.props.onGetName(response.data);
}
So I guess you need some thing like importing components from one file to another. So you have options to import and export components from another file since React components are basically Objects. In index.js if you have something like
const headerTitle = <HeaderTitle name="About Page" />;
export default headerTitle;
and in app.js
import React, { PropTypes, Component } from 'react';
import { Grid, Nav, Navbar, NavItem, Jumbotron } from 'react-bootstrap';
import { Link } from 'react-router';
import { LinkContainer, IndexLinkContainer } from 'react-router-bootstrap';
import HeaderTitle from '/// put the file relative location to app.js"
function HeaderTitle(props) {
return <h1>{props.name}</h1>;
}
class App extends React.Component {
constructor(props) {
super(props);
}
render() { ...
<p>{headerTitle.props.name}</p>
}