Converting a react redux block to react native - reactjs

I am new to react native,I have a block of code for a form in react, need to convert this into react native elements using the same let variable AddTodo
let AddTodo = ({ dispatch }) => {
let input
return (
<div>
<form onSubmit={e => {
e.preventDefault()
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value))
input.value = ''
}}>
<input ref={node => {
input = node
}} />
<button type="submit">
Add Todo
</button>
</form>
</div>
)
}
AddTodo = connect()(AddTodo)
Can anyone help me here? This is the source code

Here is simple code for react-native, that convert from your react code.
You can find more about react-native here.
in html we use for group other element so for react-native using
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
class AddTodo extends Component {
constructor(props) {
super(props);
this.state = {
todoText: ''
};
}
render() {
return (
<View>
<TextInput
onChangeText={(todoText) => this.setState({todoText})}
value={this.state.todoText}
/>
<TouchableHighlight onPress={() => {
if(this.state.todoText) {
this.props.addTodo(input.value);
this.setState({ todoText: '' })
}
}}>
<Text>Add Todo</Text>
</TouchableHighlight>
</View>
);
}
}
function mapStateToProps(state) {
return {};
}
function mapDispatchToProps(dispatch) {
return {
addTodo: bindActionCreators(addTodo, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AddTodo);
You can find react-native redux todo example here

Related

Filter values from state

AutoComplete Class
import React from 'react';
import axios from 'axios';
import DeleteItem from '../DeleteItem/DeleteItem'
export default class AutoComplete extends React.Component{
constructor(props){
super(props)
this.state={
suggestions:[],
text:'',
persons:[],
delsuggestions:[],
}
this.delete = this.delete.bind(this);
}
// Here I am calling api
componentDidMount() {
axios.get(`https://jsonplaceholder.typicode.com/users`)
.then(res => {
const persons = res.data;
this.setState({ persons:persons });
})
}
//on entering values
onTextChanged= (e) =>{
const value=e.target.value;
let suggestions=[];
if(value.length>0){
suggestions=this.state.persons.map(item =>(item.name))
.filter(function(val){
return val.indexOf(value) > -1
})
}
this.setState(()=>({suggestions:suggestions,text:value}))
}
//On selecting a value from listitems
personSelected(value){
this.setState(()=>({
text:value,
persons:[],
}))
}
//delete function
handleDelete=id =>{
let delsuggestions=[];
this.setState(()=>({delsuggestions:[...this.state.suggestions].filter(el => el!= id)}))
console.log('delsuggestions'+delsuggestions)
}
//listing out filtered items
renderPersons(){
const {persons}=this.state
return(
<React.Fragment>
{this.state.suggestions.map(item => (
<DeleteItem
key={item}
searchitem={item}
onDelete={this.handleDelete}
/>
))}
</React.Fragment>
)
}
//render function
render(){
const {text} = this.state;
return(<div>
<input value={text} onChange={this.onTextChanged} type='text' style={{backgroundColor:'pink'}} />
{this.renderPersons()}
</div>)
}
}
DeleteItem Class
import React, { Component } from "react";
class DeleteItem extends Component {
render() {
return (
<div className="deletebuttom">
{this.props.searchitem} <button
onClick={() => this.props.onDelete(this.props.searchitem)}
>
Delete
</button>
</div>
);
}
}
export default DeleteItem;
what's problem with the below filter function
handleDelete=id =>{
let delsuggestions=[];
this.setState(()=>({delsuggestions:this.state.suggestions.filter(el => el.id != id)}))
console.log('delsuggestions'+delsuggestions)
}
I am not getting filtered values in delsuggestions.When I debug "unexpected end of input" is displayed onhover of el.

Rapid onChange causes OnClick not to register

I set the state when I onChange of a input field and then have a submit function on the onClick. The onClick doesn't register at all if I click it within a second or so of the last input.
I have cut everything out of the component that I don't need and am left this:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Loader from '../utils/Loader';
import './CustomMenu.scss';
import {custom_getCategory} from '../../actions/customActions';
import propsDebug from '../utils/propsDebug';
class CustomMenu extends Component {
constructor(props) {
super(props);
this.state = {
input: "",
customWords: [],
}
this.formToState = this.formToState.bind(this);
this.submit = this.submit.bind(this);
}
formToState(e) {
const {value, name} = e.target;
this.setState({[name]: value});
}
submit() {
const {input} = this.state;
this.setState( state => {
state.input = "";
console.log("newState", state);
return state;
});
}
render() {
const {input, customWords} = this.state;
return (
<div className="CustomMenu">
<input name="input" value={input} onChange={(e) => this.formToState(e)}/>
<button onClick={(e) => {
console.log("onClick");
this.submit(e);
}} style={{margin: "10px"}}>Add</button>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => ({
data: state[ownProps.reduxState],
custom: state.custom,
})
export default connect(mapStateToProps, {custom_getCategory})(CustomMenu);
Any ideas how I can fix this? I feel I have used this pattern many times before without issues - I don't know what I am missing.
<button onClick={(e) => {
console.log("onClick");
this.submit(e);
}} style={{margin: "10px"}}>Add</button>
I think the bug is from the callback you passed to your onClick(). You need to return the this.submit() before you can get it to fire.
<button onClick={(e) => (
console.log("onClick");
this.submit(e);
)} style={{margin: "10px"}}>Add</button>
use an implicit return instead.

Upload image to redux and show in React-Konva

I have try to upload image to Redux and show in of React-Konva in many ways. But it isn't work. Both in base64 and blob. But in normal situation like using component's state to keep data(base64) it's work. I don't know why.
In my component just have button for upload and React-Konva Component for show image
this is error from base64 store in redux and show to Image Tag
class UploadButton extends Component{
constructor(props){
...
this.handleUpload = this.handleUpload.bind(this);
}
handleUpload({target}){
const reader = new FileReader();
const file = target.files[0];
reader.onloadend = () => {
this.props.dispatch({
type: 'UPLOAD_IMAGE',
image: reader.result,
});
};
reader.readAsDataURL(file);
}
render(){
return(
<div>
<input
value="Upload"
type="button"
onClick={ () => { this.uploadInput.click() } }
/>
<input
id="inputUpload"
ref={ (ref) => { this.uploadInput = ref } }
type="file"
style={ { display: 'none' } }
onChange = { (event) => { this.handleUpload(event) }}
/>
</div>
);
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Stage, Layer, Image } from 'react-konva';
class ShowImage extends Component {
constructor(props){
super(props);
this.props = props;
this.state = {
image : null,
}
}
render(){
return (
<Stage
width={ 500 }
height={ 500 }
>
<Layer>
<Image image={ this.props.image} ></Image>
</Layer>
</Stage>
);
}
}
const mapStateToProps = ( state ) => ({
image : state.image,
});
export default connect(mapStateToProps)(ShowImage);
To use the image in react-konva you have to create a native instance of window.Image.
class VaderImage extends React.Component {
state = {
image: new window.Image()
};
componentDidMount() {
this.state.image.src = this.props.image;
this.state.image.onload = () => {
// need to update layer manually
this.imageNode.getLayer().batchDraw();
};
}
render() {
return (
<Image
image={this.state.image}
y={250}
ref={node => {
this.imageNode = node;
}}
/>
);
}
}
https://konvajs.github.io/docs/react/Images.html

How do i validate forms with semantic-ui-react

I'm using the official Semantic UI React components to create a web application. I have a form on a search page, which contains an input field.
import React from 'react'
import {Form} from "semantic-ui-react";
import RadiusOfSearchInput from "./RadiusOfSearchInput";
const NearbyShopsSearchForm = (props) => {
const { onSubmit, size, action, onChange, value, style } = props
return (
<Form onSubmit={onSubmit}>
<RadiusOfSearchInput size={size}
action={action}
onChange={onChange}
value={value}
style={style} />
</Form>
)
}
export default NearbyShopsSearchForm
The component that uses the form is as shown below:
import React, { Component } from 'react'
import {Menu, Container, Segment} from 'semantic-ui-react'
import ShopCardList from "../components/ShopCardList";
import axios from 'axios';
import NearbyShopsSearchForm from "../components/NearbyShopsSearchForm";
class NearbyShopsPage extends Component {
constructor(props) {
super(props)
this.state = {
radius: '',
shops: []
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange = (e, { value } ) => {
this.setState({ radius: value })
}
handleSubmit = (e, data) => {
const { radius } = this.state
const url = `/api/shops/#33.846978,-6.775816,${radius}`
axios.get(url)
.then((response) => {
this.setState({ shops: response.data })
})
.catch((error) => {
console.log(error)
})
e.preventDefault()
}
render() {
const { radius } = this.state
return (
<Segment basic>
<Menu fixed='top' size='huge' borderless>
<Menu.Item>
<NearbyShopsSearchForm onSubmit={this.handleSubmit}
size='large'
action={{ color: 'teal', content: 'Search', size: 'small' }}
onChange={this.handleChange}
value={radius}
style={{ width: '17.5em' }} />
</Menu.Item>
</Menu>
<Container style={{ marginTop: '5.5em' }}>
<ShopCardList shops={this.state.shops}/>
</Container>
</Segment>
)
}
}
export default NearbyShopsPage
I want to validate the form so it won't submit values other than decimals, which are valid values to represent a distance. I didn't find validation support in the SUIR official documentation. I'm aware of the redux-form possibility, but i fail to implement it correctly. what's the recommended and simplest way to implement the data validation feature?

React + Redux Update issue

I have this class:
import React from 'react';
import {Link} from 'react-router';
import '../../styles/about-page.css';
import Item from './Item';
// Redux
import { connect } from 'react-redux';
import actions from '../../redux/actions';
import { bindActionCreators } from 'redux';
// Auth
import Auth from '../../modules/Auth';
import User from '../../constants';
class CommentForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit() {
// alert('A name was submitted: ' + this.state.value);
this.props.onFinish({
name: this.props.user.name,
userId: this.props.user.id,
comment: this.state.value
});
}
render() {
if (!this.props.user || !this.props.user.name) return <div/>;
return (<div className="item">
{this.props.user.name}:
<label style={{width: '60%', margin: '10px'}}>
<input style={{width: '100%'}} type="text" value={this.state.value} onChange={this.handleChange.bind(this)} />
</label>
<input style={{width: '16%', display: 'inline-block', margin: '10px'}} type="submit" value="Enviar" onClick={this.handleSubmit.bind(this)}/>
</div>
);
}
}
#connect((state) => state)
class ItemPage extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null,
pret: null
};
}
componentWillMount() {
let self = this;
this.props.actions.getPret(this.props.routeParams.id).then(function(a) {
self.setState({
pret: self.props.pret
})
});
if (Auth.isUserAuthenticated()) {
User.getBearer(Auth, function(info) {
self.setState({user: info});
});
}
}
onFinish(comment) {
//changing the state in react
//need to add '6' in the array
//create a copy of this.state.a
//you can use ES6's destructuring or loadash's _.clone()
const currentStatePretCopy = Object.assign({}, this.state.pret, { b: this.state.pret.comments.concat([comment])})
console.log(1, currentStatePretCopy);
currentStatePretCopy.comments.push(comment);
this.props.actions.updatePret(currentStatePretCopy);
}
render() {
let self = this;
if (!this.state || !this.state.pret) return <div/>;
return (<div>
<section>
<Item full={true} user={this.state.user} item={this.state.pret} actions={this.state.actions}/>
</section>
<div>
<CommentForm user={this.state.user} pret={this.state.pret} onFinish={this.onFinish.bind(this)}/>
{/* TODO: ad here */}
{this.state.pret.comments && this.state.pret.comments.length ? this.state.pret.comments.map(function (comment, index) {
return (<div className="item" key={index}> by <Link to={'/user/' + comment.userId}> #{comment.name} </Link> : {comment.comment} </div>);
}) : null}
</div>
</div>
);
}
}
function mapStateToProps (state) {
return {
pret: state.prets[0]
};
}
function mapDispatchToProps (dispatch) {
return {
actions: bindActionCreators(actions, dispatch)
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(ItemPage);
When i want to update the object, since props should be immutable, the documentation suggest cloning the object and put it in the state.
I am modifying the state with the new value and sending it to Redux actions but the system complains:
Uncaught Error: A state mutation was detected between dispatches, in the path 'prets.0.comments.1'. This may cause incorrect behavior.
Since i copy the object I do not know how should I update the store via React+Redux
The comments array is still the original one. So you are mutating the original object with push.
Replace
currentStatePretCopy.comments.push(comment);
With
currentStatePretCopy.comments = currentStatePretCopy.comments.concat([comment])
And everything should work fine

Resources