how to pass the ref from a child component
import React, { Component } from "react";
import Text from "./Text";
import { TextInput, View, I18nManager } from "react-native";
import colors from "../styles/colors";
export default class Input extends Component {
render() {
return (
<View>
<View style={{ padding: 10 }}>
<Text>
{this.props.label}
</Text>
</View>
<TextInput
{...this.props}
placeholder={this.props.label}
/>
</View>
);
}
}
I'm trying to focus on next input with this reusable component but it's not working.
<Input
label={'username'}
returnKeyType={"next"}
onSubmitEditing={() => this.refs.password.focus()}
/>
<Input label={'password'} ref={'password'} />
Here's an example of how to do this:
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
constructor(props) {
super(props);
this.passwordRef = React.createRef();
}
handleSubmit = e => {
this.passwordRef.current.focus();
};
render() {
return (
<React.Fragment>
<input placeholder="email" />
<button onClick={this.handleSubmit}>next</button>
<hr />
<input ref={this.passwordRef} placeholder="password" />
</React.Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
CodeSandbox here.
Another way, using child:
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
constructor(props) {
super(props);
this.passwordRef = React.createRef();
}
render() {
return (
<React.Fragment>
<input placeholder="email" />
<Child passwordRef={this.passwordRef} />
<hr />
<input ref={this.passwordRef} placeholder="password" />
</React.Fragment>
);
}
}
const Child = ({ passwordRef }) => {
return <button onClick={() => passwordRef.current.focus()}>focus</button>;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Short answer: this.ref.current instead of this.ref.
You can utilize React.forwardRef:
const Input = React.forwardRef((props, ref) => (
<View>
<View style={{ padding: 10 }}>
<Text>{this.props.label}</Text>
</View>
<TextInput {...this.props} ref={ref} placeholder={this.props.label} />
</View>
));
export default Input;
And once you've defined Input using forwardRef, you can use the ref attribute as you normally . would:
class App extends React.Component {
inputRef = React.createRef();
focusInput = () => {
this.inputRef.current.focus();
}
render() {
return <Input ref={this.inputRef} />;
}
}
Related
I'm trying to render embed tweets with ReactDOMServer.renderToString but it doesn't work.
I'm using react-twitter-embed npm package.
I also tried with another jsx functions it works. But tweet embed doesn't work. My code and demo in below;
Codesandbox demo
Doesn't work.
tweet = x =>
ReactDOMServer.renderToStaticMarkup(
<div>
<TwitterTweetEmbed tweetId={x} />
</div>
);
Works
icon = x => ReactDOMServer.renderToString(<FaTags size={x} />);
Full Code
import React, { Component, Fragment } from "react";
import ReactDOMServer from "react-dom/server";
import { TwitterTweetEmbed } from "react-twitter-embed";
import { FaTags } from "react-icons/fa";
import { render } from "react-dom";
export default class App extends Component {
constructor() {
super();
this.state = {
name: "React"
};
}
tweet = x =>
ReactDOMServer.renderToStaticMarkup(
<div>
<TwitterTweetEmbed tweetId={x} />
</div>
);
icon = x => ReactDOMServer.renderToString(<FaTags size={x} />);
render() {
let tweetxx = "[tweet]1216022644614545409[/tweet]";
let tweetx = tweetxx.replace(/\[tweet\]([0-9]{1,}?(?=\[\/tweet\]))\[\/tweet\]/g,"$1");
return (
<Fragment>
<span>Doesn't work</span>
<div dangerouslySetInnerHTML={{ __html: this.tweet(tweetx) }} />
<hr />
<span>Works</span>
<div dangerouslySetInnerHTML={{ __html: this.icon(40) }} />
<hr />
<span>Works (Directly)</span>
<br />
<span>{tweetxx}</span>
<br />
<span>{tweetx}</span>
<TwitterTweetEmbed tweetId={tweetx} />
</Fragment>
);
}
}
render(<App />, document.getElementById("root"));
I would like to know how to accomplish this.
Passing an event from Parent to Child/Child, by this example: I have Apps.js, then FormDynamic.js and two Inputs. I want to pass handleChange from the Apps.js to FormDynamic.js and then to InputTextField.js and get the value from the App.js on the submitForm function.
//Apps.js
import React, {Component} from 'react';
import FormDynamic from './components/FormDynamic'
class App extends Component {
constructor(props)
{
super(props);
this.state={
fields: [
{id:"101", name:"101", placeholder:"Enter Value 1",input_type:"text",required:true},
{id:"102", name:"102", placeholder:"Enter Value 2",input_type:"number",required:true}
]
}
this._handleChange = this._handleChange.bind(this);
}
_handleChange = event =>{
this.setState({
[event.currentTarget.id]: event.currentTarget.value
});
};
submitForm = event =>{
const {fields, ...inputFields} = this.state;
console.log(fields);
console.log(inputFields);
event.preventDefault();
};
render(){
return (
<div className="App">
<FormDynamic fields={this.state.fields} handleChange={this._handleChange} />
<button onClick={this.submitForm}>Enviar Datos</button>
</div>
);
}
}
export default App;
//FormDynamic.js
import React, {Component} from 'react';
import InputTextField from './InputTextField'
import InputNumberField from './InputNumberField'
class FormDynamic extends Component
{
constructor(props)
{
super(props);
}
render()
{
return(
<div>
{this.props.fields.map(form => {
if (form.input_type ==="text")
{
return (
<InputTextField
id={form.id}
name={form.name}
placeholder={form.placeholder}
required={form.required}
key={form.id}
onChange = {this.props.handleChange}
/>
);
}
if (form.input_type ==="number")
{
return (
<InputNumberField
id={form.id}
name={form.name}
placeholder={form.placeholder}
required={form.required}
key={form.id}
onChange = {this.props.handleChange}
/>
);
}
return null;
})}
</div>
)
};
}
export default FormDynamic;
//InputTextField.js
import React from 'react';
const InputTextField = ({id,name,placeholder,required,_handleChange}) =>
(
<div>
<input type="text"
id={id}
name={name}
required={required}
placeholder={placeholder}
onChange={_handleChange}
/>
</div>
);
export default InputTextField;
From FormDynamic.js your passing props onChange to InputTextField.js but your reading wrong props _handleChange instead read onChange props, try the below code it will work.
//InputTextField.js
import React from 'react'
const InputTextField = ({id, name, placeholder, required, onChange}) => (
<div>
<input type="text"
id={id}
name={name}
required={required}
placeholder={placeholder}
onChange={onChange}
/>
</div>
)
export default InputTextField
I have an simple application that have just two screens: Login and Home. I want to go to Home screen from Login screen. I don't want to use a Navigator, if it is possible. This is my code:
Index.js
import { AppRegistry } from 'react-native';
import App from './src/App';
AppRegistry.registerComponent('App', () => App);
App.js
class App extends Component {
constructor(props) {
super(props);
}
render() {
return(
<LoginPage />
);
}
}
export default App;
LoginPage.js
export class LoginPage extends Component{
constructor(props) {
super(props);
this.state = { email: '', password: '' };
}
goToHomePage = () => {
// HERE!!!!!!
};
onButtonPress = () => {
this.goToHomePage();
};
render(){
return(
<View>
<TextInput
style={Styles.textInput}
onChangeText={(email) => this.setState({email})}
placeholder={'Email'}
value={this.state.email}
/>
<TextInput
style={Styles.textInput}
onChangeText={(password) => this.setState({password})}
secureTextEntry
placeholder={'Password'}
value={this.state.password}
/>
<Button onPress={() => this.props.navigation.navigate('HomePage')}
title="Login"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
};
}
HomePage.js
export class HomePage extends Component{
constructor(props) {
super(props);
}
goToLoginPage = () => {
// HERE !!!!!!
};
onButtonPress = () => {
this.goToLoginPage();
};
render () {
return (
<View style={Styles.container}>
<View>
<LoginHeader Title={'Titulo do HomePage'} />
</View>
<Button
style={Styles.button}
title={'Logout'}
onPress={this.onButtonPress}
/>
</View>
)
}
}
So, how can I implement a method for move to screens with this code? I've tried to use react-native-navigation and react-navigation, but does not work for me in this case.
EDIT
I've tried to use this:
App.js
import { createStackNavigator } from 'react-navigation';
const RootStack = createStackNavigator(
{
HomePage: HomePage,
LoginPage: LoginPage,
},
{
initialRouteName: 'LoginPage',
}
);
class App extends Component {
constructor(props) {
super(props);
}
render() {
return(
<RootStack />
);
}
}
export default App;
LoginPage.js
import { createStackNavigator } from 'react-navigation';
export class LoginPage extends Component{
constructor(props) {
super(props);
this.state = { email: '', password: '' };
}
goToHomePage = () => {
// HERE!!!!!!
};
onButtonPress = () => {
this.goToHomePage();
};
render(){
return(
<View>
<TextInput
style={Styles.textInput}
onChangeText={(email) => this.setState({email})}
placeholder={'Email'}
value={this.state.email}
/>
<TextInput
style={Styles.textInput}
onChangeText={(password) => this.setState({password})}
secureTextEntry
placeholder={'Password'}
value={this.state.password}
/>
<Button onPress={() => this.props.navigation.navigate('HomePage')}
title="Login"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
};
}
Do you import React, {Component} from "react"?
How can i get the min value and max value from the rcslider third party component.git link of the api is
http://react-component.github.io/slider/
I installed the rcslider component and use the sample code
import 'rc-slider/assets/index.css';
import 'rc-tooltip/assets/bootstrap.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
const createSliderWithTooltip = Slider.createSliderWithTooltip;
const Range = createSliderWithTooltip(Slider.Range);
const Handle = Slider.Handle;
const handle = (props) => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
const wrapperStyle = { width: 400, margin: 50,padding:20 };
class Rangeslider extends React.Component {
constructor(props) {
super(props);
this.state = {
min: 0,
max: 5000,
};
}
render(){
return(
<div>
<div>
<div style={wrapperStyle}>
<p>Range with custom handle</p>
<Range min={0} max={5000} defaultValue={[0, 5000]} tipFormatter={value => `${value}`} />
<span>${this.state.min}</span>
<span style={{float:"right"}}>${this.state.max}</span>
</div>
</div>
</div>
)
}
}
export default Rangeslider
How can i get the min value and max value from the rcslider third party component.git link of the api is
http://react-component.github.io/slider/
I have used to the onChange function to change the minimum values and max values of the slider.This is solved my problem
import 'rc-slider/assets/index.css';
import 'rc-tooltip/assets/bootstrap.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
const createSliderWithTooltip = Slider.createSliderWithTooltip;
const Range = createSliderWithTooltip(Slider.Range);
const Handle = Slider.Handle;
const handle = (props) => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
const wrapperStyle = { width: 400, margin: 50,padding:20 };
class Rangeslider extends React.Component {
constructor(props) {
super(props);
this.state = {
value: [0, 5000],
};
}
render(){
return(
<div>
<div>
<div style={wrapperStyle}>
<p>Range with custom handle</p>
<Range min={0}
max={5000}
defaultValue={this.state.value}
allowCross={false}
onChange={value=>this.setState({value})} />
<span>${this.state.value[0]}</span>
<span style={{float:"right"}}>${this.state.value[1]}</span>
</div>
</div>
</div>
)
}
}
export default Rangeslider
I'm new for React and Material-UI too. I have this App.js file:
import React, {Component} from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import AppBar from 'material-ui/AppBar';
import IconButton from 'material-ui/IconButton';
import NavigationMenu from 'material-ui/svg-icons/navigation/menu';
import DrawerMenu from './DrawerMenu';
const AppBarIcon = () => (
<AppBar
title="Title"
iconElementLeft={<IconButton onClick={???}>
<NavigationMenu />
</IconButton>}
/>
);
class App extends Component {
render() {
return (
<div className="App">
<MuiThemeProvider>
<div>
<DrawerMenu />
<AppBarIcon />
</div>
</MuiThemeProvider>
</div>
);
}
}
export default App;
...and this is the DrawerMenu.js file:
import React from 'react';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
export default class DrawerSimpleExample extends React.Component {
constructor(props) {
super(props);
this.state = {open: false};
}
handleToggle = () => this.setState({open: !this.state.open});
render() {
return (
<div>
<Drawer open={this.state.open}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
</div>
);
}
}
Is there any way to set the IconButton's onClick value in App.js file to set the DrawerMenu's state open:true ? For example:
<IconButton onClick={ DrawerMenu.setState({open:true}) }>
...or something like this?
You can use props to achieve desired behavior.
Example
const AppBarIcon = (props) => (
<AppBar
title="Title"
iconElementLeft={<IconButton onClick={props.onIconClick}>
<NavigationMenu />
</IconButton>}
/>
);
class App extends Component {
constructor(props) {
super(props);
this.state = { isOpen: false };
}
onIconClick = () => {
this.setState((prevState) => ({ isOpen: !prevState.isOpen }));
}
render() {
return (
<div className="App">
<MuiThemeProvider>
<div>
<DrawerMenu isOpen={this.state.isOpen} />
<AppBarIcon onIconClick={this.onIconClick} />
</div>
</MuiThemeProvider>
</div>
);
}
}
export default class DrawerSimpleExample extends React.Component {
constructor(props) {
super(props);
this.state = {open: false};
}
handleToggle = () => this.setState({open: !this.state.open});
render() {
return (
<div>
<Drawer open={this.props.isOpen}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
</div>
);
}
}