I have a modal with a React-Hook-Form that send data to my API and saves it in a MySql database, but when i click on the button, only 4 columns are filled('id', createdAt, updatedAt and user_id), and I have more 3 columns('title', 'description', 'photo').
export default function FeedModal() {
const [form, setForm] = useState([]);
const { register, handleSubmit, setValue } = useForm();
const [isModalVisible, setModalVisible] = useState(false);
useEffect(() => {
register({ title: 'title' });
register({ description: 'description' })
}, [register]);
const onSubmit = async ({ title, description, photo }) => {
const data = { title, description, photo };
await api.post('/posts/1/create')
.then(response => setForm(response(data)))
.then(JSON.stringify(form))
.catch(console.error());
return () => handleSubmit(onSubmit);
}
const toogleModal = () => {
setModalVisible(!isModalVisible);
}
My form:
<View style={styles.Card}>
<View style={styles.pubCard}>
<Text style={styles.intro}>Criar publicação</Text>
<TextInput
value={form.title}
name={'title'}
ref={register({ required: true })}
onChangeText={text => setValue("title", text, { shouldValidate: true })}
multiline={true}
style={styles.titleInput}
placeholder="Titulo">
</TextInput>
</View>
<View style={styles.btnView}>
<TouchableOpacity style={styles.upload} title="Selecionar Foto" >
<Text style={{ color: 'white', fontFamily: 'Montserrat_400Regular', textAlign: 'center' }}>Selecionar Foto</Text>
</TouchableOpacity>
</View>
<KeyboardAvoidingView style={styles.descView}>
<TextInput
value={form.description}
name={"description"}
ref={register({ required: true })}
onChangeText={text => setValue("description", text)}
multiline={true}
style={styles.descInput}
placeholder="Nos descreva com detalhes sobre o caso do seu Pet"></TextInput>
</KeyboardAvoidingView>
<View style={styles.buttons}>
<TouchableOpacity onPress={toogleModal} style={styles.ButtonClose}><Text style={{ color: 'white', fontFamily: 'Montserrat_400Regular' }}>Fechar</Text></TouchableOpacity>
<TouchableOpacity onPress={handleSubmit(onSubmit)} style={styles.ButtonClose}><Text style={{ color: 'white', fontFamily: 'Montserrat_400Regular' }}> Criar</Text></TouchableOpacity>
</View>
</View>
perhaps useFieldArray will be the better usage here since you are talking about the insert.
https://react-hook-form.com/api#useFieldArray
you can then use the insert action. eg:
import React from "react";
import { useForm, useFieldArray } from "react-hook-form";
function App() {
const { register, control, handleSubmit, reset, trigger, setError } = useForm({
// defaultValues: {}; you can populate the fields by this attribute
});
const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({
control,
name: "test"
});
return (
<form onSubmit={handleSubmit(data => console.log(data))}>
<ul>
{fields.map((item, index) => (
<li key={item.id}>
<input
name={`test[${index}].firstName`}
ref={register()}
defaultValue={item.firstName} // make sure to set up defaultValue
/>
<Controller
as={<input />}
name={`test[${index}].lastName`}
control={control}
defaultValue={item.lastName} // make sure to set up defaultValue
/>
<button type="button" onClick={() => remove(index)}>Delete</button>
</li>
))}
</ul>
<button
type="button"
onClick={() => insert(1, { firstName: "appendBill", lastName: "appendLuo" })}
>
append
</button>
<input type="submit" />
</form>
);
}
Related
I want to create an application screen, in that screen it can show 2 flatlists from different api, I call it using a button.
For that process I was successful, but I want to add a search feature by reading every list that is called or active at that time, but this doesn't work. And if I take it also does not work. In this flatlist I also want to be able to move the detail pages.
This is for my college semester assignment.
import {
Box,
Text,
Image,
Heading,
Center,
ScrollView,
Spinner,
FlatList,
Pressable,
View,
HStack,
Button,
} from 'native-base';
import React, { Component } from 'react';
import { Dimensions, TouchableOpacity, StatusBar } from 'react-native';
import {LinearGradient} from 'expo-linear-gradient';
import { Ionicons, Entypo } from '#expo/vector-icons';
import { ListItem, SearchBar } from '#rneui/themed';
const windowWidth = Dimensions.get('window').width;
class Legal extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
categories: ['apps', 'products'],
contentSwitcher: false,
isFetching: false,
searchTxt: null,
error: null,
temp: [],
};
}
async getApps() {
try {
const response = await fetch(
'https://ojk-invest-api.vercel.app/api/apps'
);
const json = await response.json();
this.setState({ data: json.data.apps });
} catch (error) {
console.error(error);
} finally {
this.setState({ isLoading: false, contentSwitcher: false });
}
}
async getProducts() {
try {
const response = await fetch(
'https://ojk-invest-api.vercel.app/api/products'
);
const json = await response.json();
this.setState({ data: json.data.products, contentSwitcher: true });
} catch (error) {
console.error(error);
} finally {
this.setState({ isLoading: false });
}
}
setResult = (res) => {
this.setState ({
data: [...this.state.data, ...res.data.apps],
temp: [...this.state.temp, ...res.data.apps],
error: res.error || null,
isLoading: false,
});
};
renderHeader = () => {
return <SearchBar placeholder='Cari ...'
lightTheme round editable={true}
value={this.state.searchTxt}
onChangeText={this.updateSearch}
/>
};
updateSearch = searchTxt => {
this.setState({searchTxt}, () => {
if ('' == searchTxt) {
this.setState({
data: [...this.state.temp],
});
return;
}
this.state.data = this.state.temp.filter(function (item) {
return item.name.includes(searchTxt);
}).map(function({ id, name, type }) {
return {id, name, type};
});
});
};
componentDidMount() {
this.getApps();
}
onRefresh = () => {
this.setState({ isFetching: true }, () => {
this.getApps();
});
};
renderItem = ({ item }) => {
const { navigation } = this.props;
return (
<>
<Pressable
style={{ padding: 20, backgroundColor: 'white' }}
onPress={() => navigation.navigate('Detail Produk', { data: item })}>
<Center>
<View
style={{
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
fontSize: 16,
width: windowWidth - 40,
textAlign: 'justify',
marginTop: 6,
}}>
{item.name}
</Text>
<Text
style={{
color: '#808080',
fontSize: 14,
width: windowWidth - 40,
textAlign: 'justify',
marginTop: 6,
}}>
{this.state.contentSwitcher ? item.management : item.owner}
</Text>
</View>
</Center>
</Pressable>
<View style={{ borderWidth: 0.5, borderColor: '#cccccc' }}></View>
</>
);
};
render() {
const { data, isLoading, isFetching } = this.state;
return (
<View style={{ flex: 1, justifyContent: 'center'}}>
<HStack alignItems="center" bgColor="#fff" p="1" w={window.width}>
<Pressable m="2" rounded="8" p="2" flex={1} textAlign="center">
<Button onPress={() => this.getApps()}
leftIcon={<Ionicons name="folder" color="white" />}
colorScheme="green"
>
Aplikasi
</Button>
</Pressable>
<Pressable m="2" rounded="8" p="2" flex={1} textAlign="center">
<Button onPress={() => this.getProducts()}
leftIcon={<Entypo name="box" color="white" />}
colorScheme="green"
>
Produk
</Button>
</Pressable>
</HStack>
{isLoading ? (
<Spinner size="large" color="#AA0002" />
) : (
<FlatList
ListHeaderComponent={this.renderHeader}
data={data}
keyExtractor={({ link }, index) => link}
renderItem={this.renderItem}
onRefresh={this.onRefresh}
refreshing={isFetching}
/>
)}
</View>
);
}
}
export default Legal;
i tried to show search result feature by using flatlist (json API) and search bar in my code, but i found this error and can't solve it. I can run the search but can't display the search results, can anyone help me solve this error, because this is for my college assignment
this is my code
import {
Box,
Text,
Image,
Heading,
Center,
ScrollView,
Spinner,
FlatList,
Pressable,
View,
Stack,
} from 'native-base';
import React, { Component } from 'react';
import { Dimensions } from 'react-native';
import { ListItem, SearchBar } from '#rneui/themed';
const windowWidth = Dimensions.get('window').width;
class Ilegal extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
isFetching: false,
searchTxt: null,
error: null,
temp: [],
};
};
async getData() {
try {
const response = await fetch(
'https://ojk-invest-api.vercel.app/api/illegals'
);
const json = await response.json();
this.setState({ data: json.data.illegals });
this.setResult(json);
} catch (error) {
console.error(error);
} finally {
this.setState({
isLoading: false,
isFetching: false,
});
}
};
setResult = (res) => {
this.setState ({
data: [...this.state.data, ...res],
temp: [...this.state.temp, ...res],
error: res.error || null,
isLoading: false,
});
};
renderHeader = () => {
return <SearchBar placeholder='Cari Perusahaan..'
lightTheme round editable={true}
value={this.state.searchTxt}
onChangeText={this.updateSearch}
/>
};
updateSearch = searchTxt => {
this.setState({searchTxt}, () => {
if ('' == searchTxt) {
this.setState({
data: [...this.state.temp],
});
return;
}
this.state.data = this.state.temp.filter(function (item) {
return item.name.includes(searchTxt);
}).map(function({ id, name, type }) {
return {id, name, type};
});
});
};
componentDidMount() {
this.getData();
};
onRefresh = () => {
this.setState({ isFetching: true }, () => {
this.getData();
});
};
renderItem = ({ item }) => {
const { navigation } = this.props;
return (
<>
<Pressable
style={{ padding: 20, backgroundColor: 'white' }}
onPress={() => navigation.navigate('Detail Ilegal', { data: item })}>
<Center>
<View
style={{
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
fontSize: 16,
width: windowWidth - 40,
textAlign: 'justify',
marginTop: 6,
}}>
{item.name}
</Text>
<Text
style={{
color: '#808080',
fontSize: 14,
width: windowWidth - 40,
textAlign: 'justify',
marginTop: 6,
}}>
{item.type}
</Text>
</View>
</Center>
</Pressable>
<View style={{ borderWidth: 0.5, borderColor: '#cccccc' }}></View>
</>
);
};
render() {
const { data, isLoading, isFetching, error} = this.state;
return (
<View style={{ flex:1, justifyContent:'center', backgroundColor:'white', flexDirection: 'column', }}>
{isLoading ? (
<Spinner size="large" color="#AA0002" />
) : (
<FlatList
ListHeaderComponent={this.renderHeader}
data={data}
keyExtractor={({ link }, index) => link}
renderItem={this.renderItem}
onRefresh={this.onRefresh}
refreshing={isFetching}
/>
)}
</View>
);
}
}
export default Ilegal;
you can help me for fixed this error ?
I think the error is in setResult() function as far as I could understood your set result function. You are setting data like this
this.setState({ data: json.data.illegals });
in getData() while you are fetching data from API but you are sending json as parameter to setResult which is object. Try to change your setResult() as below:
setResult = (res) => {
this.setState ({
data: [...this.state.data, ...res.data.illegals],
temp: [...this.state.temp, ...res.data.illegals],
error: res.error || null,
isLoading: false,
});
};
I wanted to show a list of data in my app, I already have backend API that can get the data from the server but when I trying to make it appear in my react native app, it wont appear. Below is the data that get from API
here is the code for show the data in a list view in react native apps
import React, { useState, useEffect,Component,onMount} from 'react';
import {View,Text, Button, StyleSheet,TextInput,ListView,ActivityIndicator,Platform} from 'react-native';
import {useNavigation} from'#react-navigation/native';
import {StatusBar} from'expo-status-bar';
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
useEffect(()=>{
return fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('Third', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={ (rowData) => <Text style={styles.rowViewContainer}
onPress={this.Showlist.bind(
this, rowData.user,
rowData.job,
rowData.jobid,
rowData.machinecode,
rowData.startTime
)} >
{rowData.job}
</Text> }
/>
</View>
);
}
const styles = StyleSheet.create({
MainContainer_For_Show_StudentList_Activity :{
flex:1,
paddingTop: (Platform.OS == 'ios') ? 20 : 0,
marginLeft: 5,
marginRight: 5
},
rowViewContainer: {
fontSize: 20,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
}
});
the expected output will only show the job from the database, but for now the function did not show the list view the error shown Text strings must be rendered within a component.
I was referring this webpage to implement the code : https://reactnativecode.com/insert-update-display-delete-crud-operations/
on the example it show function well but when I try to implement it, it cant work :(
updated but still having same error
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
const[dataSource,setdataSource]=useState();
useEffect(()=>{
return fetch('http://localhost/api/findid.php')
.then((response) => response.json())
.then((responseJson) => {
let ds = new FlatList.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
setIsLoading(false)
setdataSource(ds.cloneWithRows(responseJson))
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<FlatList
dataSource={dataSource}
keyExtractor={item=>item.user}
ItemSeparatorComponent= {ListViewItemSeparator()}
renderItem={ (item) => <Text style={styles.rowViewContainer}>{item.job}</Text> }
/>
</View>
);
}
Ok here are the steps to follow:
Use flatlist
Your data source should be a regular array. So, you can use the response from your api as it is.
renderRow should change as renderItem
renderSeparator should change as ItemSeparatorComponent
here is the final form:
const[isLoading,setIsLoading]=useState(true);
const [data, setData]=useState([]);
.......
fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
//you can't use setState inside function components. :)
setData(responseJson);
setLoading(false);
})
.catch((error) => {
console.error(error);
})
.......
<FlatList
data={data}
keyExtractor={item => item.jobid} //it should be unique. change it
renderItem={({item}) => <Text>{item.job}</Text>}
/>
This should solve your issue for now but keep in mind these too:
Looks like you don't know differences between class components and function components. Do your research
Flatlist has it's own performance configurations. Research and implement them.
does anyone have an example of a default value used in the library react-native-dropdown-picker used hooks e function, or another libre that makes this msm function simpler.
export default function OrphanageData() {
const [date, setDate] = useState(new Date())
const [value, setValue] = useState();
const [items, setItems] = useState([{}]);
let controller;
return (
<>
<StatusBar backgroundColor="#15c3d6"/>
<ScrollView style={styles.container} contentContainerStyle={{ padding: 24 }}>
<Text style={styles.title}>Compras</Text>
<Text style={styles.label}> ID - Brinco</Text>
<TextInput
style={styles.input}
/>
<DropDownPicker
items={items}
controller={instance => controller = instance}
onChangeList={(items, callback) => {
new Promise((resolve, reject) => resolve(setItems(items)))
.then(() => callback())
.catch(() => {});
}}
defaultValue={value}
onChangeItem={item => setValue(item.value)}
/>
<RectButton style={styles.nextButton} onPress={() => {}}>
<Text style={styles.nextButtonText}>Cadastrar</Text>
</RectButton>
</ScrollView>
</>
)
}
This might help (Using Hooks)
export default function OrphanageData() {
const [value, setValue] = useState('usa');
const [items, setItems] = useState([
{label: 'USA', value: 'usa'},
{label: 'UK', value: 'uk'},
{label: 'France', value: 'france'},
]);
return(
<DropDownPicker
items={items}
defaultValue={value}
onChangeItem={item => setValue(item.value)}
.....
/>
);
}
I'm following the React Native documentation for fetching JSON from an API (https://reactnative.dev/docs/network). I'm new to react and wanting to fetch a wordpress list of posts through its API, but the example they use is very simple and structured differently to how the object is returned from WP.
The problem I'm having is that it is returning the JSON, but I'm unsure how to reference each item I want to display in my flatlist. The line of problem is;
.then((json) => setData(json.movies))
For this WP returned JSON, there is no movies (obviously), in the absence of a referable point what would I specify instead?
My code;
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://public-api.wordpress.com/wp/v2/sites/derbyfutsal.com/posts')
.then((response) => response.json())
.then((json) => setData(json.movies))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.title}, {item.excerpt}</Text>
)}
/>
)}
</View>
);
};
You dont have to specify anything, you can directly set the response to the state value and use it in the flatlist.
I've updated the code to display the id instead of title as its an object. You can change it anyway you want and use it.
const App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://public-api.wordpress.com/wp/v2/sites/derbyfutsal.com/posts')
.then((response) => response.json())
.then((json) => {
setData(json)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.id}</Text>
)}
/>
)}
</View>
);
};