React: map is not a function on an empty array - javascript

I am trying to add items to a shopping cart.
I have declared cart as an empty array and I am still getting the error:
TypeError: cart.map is not a function ProductContext.js:34
addItemToCart ProductContext.js:34
addItemHandler ProductCard.js:47
onClick ProductCard.js:60
Here is my context:
// ProductContext.js
import React, { createContext, useState } from "react"
import { graphql, useStaticQuery } from "gatsby"
const ProductContext = createContext({
cart: [],
addItem: () => {}
})
const Provider = ({ children }) => {
const [cart, setCart] = useState([]);
const [productsList] = useState(
useStaticQuery(
graphql`
query SkusForProduct {
skus: allStripeSku(sort: { fields: [price] }) {
edges {
node {
id
currency
price
attributes {
name
}
}
}
}
}
`
)
)
const addItemToCart = skuId => {
let itemExisted = false
let updatedCart = cart.map(item => {
if (skuId === item.sku) {
itemExisted = true
return { sku: item.sku, quantity: ++item.quantity }
} else {
return item
}
})
if (!itemExisted) {
updatedCart = [...updatedCart, { sku: skuId, quantity: 1 }]
}
setCart({ cart: updatedCart })
localStorage.setItem('stripe_checkout_items', JSON.stringify(updatedCart))
}
return (
<ProductContext.Provider value={{ skus: productsList.skus, addItem: addItemToCart }}>
{children}
</ProductContext.Provider>
)
}
export { ProductContext, Provider }
And my ProductCard
// ProductCard.js
import React, { useState, useContext } from "react"
import { ProductContext } from "../context/ProductContext"
const cardStyles = {
display: "flex",
flexDirection: "column",
justifyContent: "space-around",
alignItems: "flex-start",
padding: "1rem",
marginBottom: "1rem",
boxShadow: "5px 5px 25px 0 rgba(46,61,73,.2)",
backgroundColor: "#fff",
borderRadius: "6px",
maxWidth: "300px",
}
const buttonStyles = {
fontSize: "13px",
textAlign: "center",
color: "#fff",
outline: "none",
padding: "12px",
boxShadow: "2px 5px 10px rgba(0,0,0,.1)",
backgroundColor: "rgb(255, 178, 56)",
borderRadius: "6px",
letterSpacing: "1.5px",
}
const formatPrice = (amount, currency) => {
let price = (amount / 100).toFixed(2)
let numberFormat = new Intl.NumberFormat(["en-US"], {
style: "currency",
currency: currency,
currencyDisplay: "symbol",
})
return numberFormat.format(price)
}
const ProductCard = () => {
const [disabled] = useState(false)
const [buttonText, setButtonText] = useState("Add to Cart")
const [paymentMessage, setPaymentMessage] = useState("")
const skus = useContext(ProductContext).skus
const addItem = useContext(ProductContext).addItem
const addItemHandler = (event, skuId, quantity = 1) => {
addItem(skuId);
}
return (
<div>
{skus.edges.map(({ node: sku }) => {
return (
<div style={cardStyles} key={sku.id}>
<h4>{sku.attributes.name}</h4>
<p>Price: {formatPrice(sku.price, sku.currency)}</p>
<button
style={buttonStyles}
onClick={event => addItemHandler(event, sku.id)}
disabled={disabled}
>
{buttonText}
</button>
{paymentMessage}
</div>
)
})}
</div>
)
}
export default ProductCard
I have logged the output of cart in the addItemToCart function and I get an empty array.
Not sure what I've done wrong.
Any help would be greatly appreciated!

Here is the problem line of code:
setCart({ cart: updatedCart })
After that runs, cart will no longer be an array (it will be an object with the property "cart", which is an array) and therefore not have a map function.

Related

How to change prop of Material UIs Button component based on screen size breakpoint when using a class component

Im using Material UI's Button component and would like to conditionally determine the variant of the button. That is, on screens medium and up, the variant should be 'outlined' and when the screen is smaller than medium, the variant type should be none. I am using a class component. I have done my research to see what others have done. I have seen the method of using useMediaQuery method but that would require me to change the component to a functional component. Im not sure if I know if that is a good idea because the component is rather a large one and that means will be a bit confusing to convert. I also tried using a ternary operator like this:
const variantType = theme.breakpoints.down("md") ? '' : 'outline';
<Button variant={variantType}>
Food Pick
</Button>
But this didnt do the job. Is there any other way to accomplish this?
Update: Here is my code after trying to wrap the component but in a functional component but its giving an error:
import { withStyles, withTheme, useTheme } from '#material-ui/core';
import PropTypes from 'prop-types';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import Grid from '#material-ui/core/Grid';
import { PulseLoader } from 'react-spinners';
import Icon from '#material-ui/core/Icon';
import Chip from '#material-ui/core/Chip';
import useMediaQuery from '#material-ui/core/useMediaQuery';
const styles = theme => ({
beta: {
height: '17px',
fontSize: '12px',
marginLeft: '10px'
},
scrollContainer: {
flex: 1,
maxHeight: '400px',
minHeight: '300px',
overflowY: 'auto'
},
progressContainer: {
height: '350px',
},
modalDescription: {
color: theme.palette.text.secondary,
marginTop: '20px',
},
button: {
marginTop: '20px',
marginLeft: '10px',
marginRight: '10px',
},
smartSuggestContainer: {
textAlign: 'right',
paddingRight: '35px',
[theme.breakpoints.down('xs')]: {
display: 'flex',
justifyContent: 'center',
flexDirection: 'row',
margin: '40px 0'
},
},
});
export default function MyComponentWrapper({ ...rest }) {
const theme = useTheme();
const mediumScreen = useMediaQuery(theme.breakpoints.down('md'));
return <FoodDescriptions {...rest} mediumScreen={mediumScreen} />;
}
class FoodDescriptions extends Component {
static PAGE_SIZE = 25;
constructor(props) {
super(props);
this.state = {
showFoodDescriptionsModal: false,
dataLoaded: false,
data: [],
page: 0,
sortBy: 'return',
sortDir: 'desc',
};
}
componentDidMount() {
document.addEventListener('keydown', this.handleKeypress);
}
componentWillUnmount() {
document.removeEventListener('keydown', this.handleKeypress);
}
fetchData = async (page, sortBy, sortDir) => {
const { currentBotId } = this.props;
const offset = page * FoodDescriptions.PAGE_SIZE;
const data = await getFoodDescriptions(currentBotId, sortBy, sortDir, FoodDescriptions.PAGE_SIZE, offset);
this.setState({
dataLoaded: true,
data,
});
};
handleKeypress = (e) => {
const { showSnartConfigsModal } = this.state;
const { key } = e;
if (key === 'Escape' && showSnartConfigsModal) {
this.closeModal();
}
};
applyConfig = (botId, params) => {
const { updateConfig, botConfig, actions } = this.props;
updateConfig({ name: botConfig.name, config: Object.assign(botConfig.config, params) });
this.closeModal();
actions.showNotification({ data: 'Configuration has been applied' });
};
openModal = () => {
const { page, sortBy, sortDir } = this.state;
this.fetchData(page, sortBy, sortDir);
this.setState({
showFoodDescriptionsModal: true,
});
};
closeModal = () => {
this.setState({
showFoodDescriptionsModal: false,
});
};
changePage = (page) => {
const { sortBy, sortDir } = this.state;
this.setState({
page,
dataLoaded: false
}, () => this.fetchData(page, sortBy, sortDir));
};
changeSortBy = (sortBy) => {
/* eslint-disable-next-line prefer-destructuring */
let sortDir = this.state.sortDir;
if (sortBy === this.state.sortBy) {
sortDir = (this.state.sortDir === 'desc') ? 'asc' : 'desc';
}
this.setState({
sortBy,
sortDir,
dataLoaded: false,
}, () => this.fetchData(this.state.page, sortBy, sortDir));
};
renderEmptyState() {
const { classes } = this.props;
return (
<Grid container alignItems="center" justify="center" className={classes.progressContainer}>
<Typography className={classes.noCoinsText}>No configurations found</Typography>
</Grid>
);
}
renderLoader() {
const { classes } = this.props;
return (
<Grid container alignItems="center" justify="center" className={classes.progressContainer}>
<PulseLoader size={6} color="#52B0B0" loading />
</Grid>
);
}
renderTable() {
const { data, page } = this.state;
return (
<StrategiesTable
strategies={data}
onClickCopy={this.applyConfig}
page={page}
changePage={this.changePage}
sortBy={this.changeSortBy} />
);
}
render() {
const {
classes, userFeatures, botConfig, theme
} = this.props;
const { showFoodDescriptionsModal, dataLoaded } = this.state;
if (!botConfig) {
return null;
}
return (
<Fragment>
<div className={classes.smartSuggestContainer}>
<Button
name="discoverConfigs"
variant={theme.breakpoints.down(600) ? '' : 'outlined'}
color="primary"
size="small"
disabled={!userFeatures['smart_suggest_backtests'.toUpperCase()] || botConfig.status.toLowerCase() === STATUSES.RUNNING}
onClick={this.openModal}>
Food Buy
</Button>
</div>
</Fragment>
);
}
}
function mapStateToProps(state) {
return {
userFeatures: state.global.paywall.features,
};
}
function mapDispatchToProps(dispatcher) {
return {
actions: {
...bindActionCreators({
showNotification,
}, dispatcher)
}
};
}
connect(mapStateToProps, mapDispatchToProps)(withTheme()(withStyles(styles)(FoodDescriptions)));
Why don't you just create a functional component using useMediaQuery and returning the responsive Button ?

react native Warning: Cannot update a component from inside the function body of a different component

my code works but for some reason, I get this warning:
"Warning: Cannot update a component from inside the function body of a different component."
I think it is something to do with these lines (whan i add them i get the error):
const product = state.data.find((data) => data._id === id);
useEffect(() => {
if ((product.moistureSensor.tests !== undefined) || (product.lightSensor.tests !== undefined)) {
setDataState({ 'lightSensor': product.lightSensor.tests[product.lightSensor.tests.length - 1].status, 'muisterSensor': product.moistureSensor.tests[product.moistureSensor.tests.length - 1].status });
console.log(stateData);
}
}, []);
there is probably something logical in react that I don't understand.
this is the full code -
import React, { useContext, useEffect, useState, useRef } from 'react';
import {
Text,
StyleSheet,
Switch,
Button,
TouchableOpacity, SafeAreaView, View, ActivityIndicator
} from 'react-native';
import { client } from '../../api/SocketConfig'
import { NavigationEvents } from 'react-navigation';
import { Context as ProductDataContext } from '../../context/ProductDetailContext'
import DynamicProgressCircle from '../../components/DynamicProgressCircle';
const SensorDataShow = ({ id }) => {
const { state } = useContext(ProductDataContext);
const [isEnabled, setIsEnabled] = useState(false);
const [loading, setLoading] = useState(false);
const [stateData, setDataState] = useState({ 'lightSensor': null, 'muisterSensor': null });
const listener = (dataServer) => {
console.log(`the data from server:${dataServer}`);
if (dataServer.lightSensor !== null)
setDataState({ 'lightSensor': dataServer.lightSensor, 'muisterSensor': dataServer.muisterSensor });
setLoading(false)
}
const changeData = () => { client.on("showData", listener) }
const emitGetData = () => { client.emit("GetData", id) }
let timer = useRef(null);
useEffect(() => {
if (loading === true) {
console.log('timeout started')
timer.current = setTimeout(() => {
setLoading(false)
console.log('i am after timeout');
}, 35000);
} return () => clearTimeout(timer.current);
}, [loading]);
const product = state.data.find((data) => data._id === id);
useEffect(() => {
if ((product.moistureSensor.tests !== undefined) || (product.lightSensor.tests !== undefined)) {
setDataState({ 'lightSensor': product.lightSensor.tests[product.lightSensor.tests.length - 1].status, 'muisterSensor': product.moistureSensor.tests[product.moistureSensor.tests.length - 1].status });
console.log(stateData);
}
}, []);
useEffect(() => {
changeData();
return () => {
client.removeAllListeners('showData', listener);
}
}, []);
return (
<>
{stateData.muisterSensor !== null && (
<>
<Text style={{ fontSize: 28 }}>Moister sensor data:</Text>
<DynamicProgressCircle
changingValues={{
Percent: parseInt(
stateData.muisterSensor
),
}}
/>
</>
)}
{stateData.lightSensor !== null && (
<Text style={{ fontSize: 28 }}>
Light sensor data:
{
stateData.lightSensor
}
</Text>
)}
{loading === false ?
<Button
title="Get Data"
style={styles.button}
onPress={() => {
emitGetData(id), setLoading(true)
}}
/>
: <ActivityIndicator animating={true} size="large" color="red" />}
</>
);
};
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#00CC00',
padding: 10,
marginTop: 10,
},
buttonON: {
alignItems: 'center',
backgroundColor: '#00CC00',
padding: 10,
marginTop: 10,
},
buttonOFF: {
alignItems: 'center',
backgroundColor: '#DB2828',
padding: 10,
marginTop: 10,
},
buttonNotOnline: {
alignItems: 'center',
backgroundColor: '#9B9D9A',
padding: 10,
marginTop: 10,
},
switch: {
alignItems: 'center',
},
});
export default SensorDataShow;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I appreciate any help I can get !

React native refreshControl ScrollView bottom-sheet ios

I am using the following component bottom-sheet, where I am implementing the pull-to-refresh, on android it works perfectly on ios it is not working.
I tried to follow various guides, but I could not figure out what the problem is that on ios it is not working.
Can anyone help me out?
Android ok:
Link: snack
import React, { useCallback, useRef, useMemo, useEffect } from 'react';
import {
StyleSheet,
View,
Text,
Button,
RefreshControl,
ToastAndroid,
Platform,
} from 'react-native';
import BottomSheet, { BottomSheetScrollView } from '#gorhom/bottom-sheet';
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const App = () => {
// hooks
const sheetRef = useRef<BottomSheet>(null);
const [refreshing, setRefreshing] = React.useState(false);
const [listData, setListData] = React.useState([]);
const onRefresh = React.useCallback(async () => {
console.log('Refresh');
setRefreshing(true);
try {
const n = getRandomInt(10, 30);
console.log(n);
let response = await fetch('https://randomuser.me/api/?results=' + n);
let responseJson = await response.json();
setListData(responseJson.results);
setRefreshing(false);
} catch (error) {
console.error(error);
}
}, [refreshing]);
useEffect(() => {
onRefresh();
}, []);
// variables
const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);
// callbacks
const handleSheetChange = useCallback((index) => {
console.log('handleSheetChange', index);
}, []);
const handleSnapPress = useCallback((index) => {
sheetRef.current?.snapTo(index);
}, []);
const handleClosePress = useCallback(() => {
sheetRef.current?.close();
}, []);
// render
const renderItem = useCallback(
(item) => (
<View key={item.login.uuid} style={styles.itemContainer}>
<Text>{item.email}</Text>
</View>
),
[]
);
return (
<View style={styles.container}>
<BottomSheet
ref={sheetRef}
index={2}
snapPoints={snapPoints}
onChange={handleSheetChange}
enableContentPanningGesture={false}
enableHandlePanningGesture={false}>
<BottomSheetScrollView
contentContainerStyle={{
backgroundColor: 'white',
//paddingTop: Platform.OS === 'ios' ? 0 : 64,
}}
contentInset={{ top: 64 }}
contentOffset={{ x: 0, y: -64 }}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
progressViewOffset={64}
colors={['#000']}
tintColor={'#000'}
/>
}>
{listData.map(renderItem)}
</BottomSheetScrollView>
</BottomSheet>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 200,
},
contentContainer: {
backgroundColor: 'white',
},
itemContainer: {
padding: 6,
margin: 6,
backgroundColor: '#eee',
},
});
export default App;

How to delete particular list item locally and from server after swipe in react native

// Here in my code am calling 2 APIS 1.( createViewGroup = async () =>)one for get data from server and set on FlatList , id,sensorType inventory,
2 second api ("SensorDelt = (rowIndex) => ") am calling for delete particular list iteam from server ,I mean after touching particular list item , i am taking id no and that id ({"password":"admin","username":"admin","sensorid":"here i have to send id no"})am sending to server and that id will be delete .
In my code am using Swipeout delete button to delete list item ,but it is working locally, not deleting from server .
Please help
import * as React from "react";
import {
View,
Text,
TextInput,
FooterTab,
Button,
TouchableOpacity,
ScrollView,
StyleSheet,
ActivityIndicator,
Header,
Alert,
AsyncStorage,
FlatList
} from "react-native";
import { Table, Row, Rows } from "react-native-table-component";
import { createStackNavigator, createAppContainer } from "react-navigation";
import { SearchBar } from "react-native-elements";
// You can import from local files
//import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from "react-native-paper";
import Swipeout from "react-native-swipeout";
class OpenApplianceIssue extends React.Component {
constructor() {
super();
this.state = {
AbcSdata: null,
loading: true,
search: "",
tableData: [],
qrData: "",
selectedPriority: "",
selectedIssue: "",
selectedReason: "",
selectedTriedRestart: "",
selectedPowerLED: "",
selectedBurning: "",
selectedNoise: "",
rowID: "",
activeRow: null
};
this.setDate = this.setDate.bind(this);
}
swipeBtns = [
{
text: "Delete",
type: "delete",
backgroundColor: "red",
underlayColor: "rgba(0, 0, 0, 1, 0.6)",
onPress: () => {
console.log("Deleting Row with Id ", this.state.activeRow);
{
this.deleteNote(this.state.activeRow);
this.onClickListener("del");
}
}
//onPress:() => this.onClickListener('tag')}
}
];
removeItem = (items, i) =>
items.slice(0, i).concat(items.slice(i + 1, items.length));
deleteNote = rowIndex => {
//add your custome logic to delete the array element with index.
// this will temporary delete from the state.
let filteredData = this.removeItem(this.state.AbcSdata, rowIndex);
this.setState({ AbcSdata: [] }, () => {
this.setState({ AbcSdata: filteredData }, () => {
console.log("Row deleted.", rowIndex);
});
});
};
setDate(newDate) {}
_loadInitialState = async () => {
const { navigation } = this.props;
const qdata = navigation.getParam("data", "NA").split(",");
var len = qdata.length;
const tData = [];
console.log(len);
for (let i = 0; i < len; i++) {
var data = qdata[i].split(":");
const entry = [];
entry.push(`${data[0]}`);
entry.push(`${data[1]}`);
tData.push(entry);
}
this.setState({ tableData: tData });
console.log(this.state.tableData);
this.setState({ loading: true });
};
// Delete Sensors ********************
SensorDelt = rowIndex => {
//const Sensorid_Data = this.props.navigation.state.params.item.id;
let filteredData = this.removeItem(this.state.AbcSdata, rowIndex);
let ABHI = filteredData//const Sensorid_Data = this.state.rowIndex;
.console
.log("Value Abhi" + filteredData);
Alert.alert("Value" + filteredData);
fetch("http:/Dsenze/userapi/sensor/delsensor", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
password: "admin",
username: "admin",
sensorid: filteredData
})
})
.then(response => {
//console.log(response);
return response.json();
})
.then(res => {
if (res.success == "true") {
Alert.alert("Sensor Added");
this.props.navigation.replace("OpenApplianceIssue");
} else {
Alert.alert("Success false");
}
});
};
handleValueChange(SensortypeId) {
this.setState({ SensortypeId });
}
// Delete sensors ***********************
onClickListener = viewId => {
if (viewId == "tag") {
this.props.navigation.navigate("AddSensors");
} else if (viewId == "del") {
//this.props.navigation.navigate('AddSensors');
this.SensorDelt();
}
};
componentDidMount() {
//this._loadInitialState().done();
this.createViewGroup();
}
// Get Sensor list ********************************************
createViewGroup = async () => {
try {
const response = await fetch(
"http://Dsenze/userapi/sensor/viewsensor",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
password: "admin",
username: "admin",
startlimit: "0",
valuelimit: "10"
})
}
);
const responseJson = await response.json();
const { sensorData } = responseJson;
this.setState({
AbcSdata: sensorData,
loading: false
});
} catch (e) {
console.error(e);
}
};
clickedItemText(OpenApplianceIssue) {
this.props.navigation.navigate("Item007", { item: OpenApplianceIssue });
//Abc = this.props.navigation.state.params.item.id;
}
updateSearch = search => {
this.setState({ search });
};
keyExtractor = ({ id }) => id.toString();
keyExtractor = ({ inventory }) => inventory.toString();
onSwipeOpen(rowId, direction) {
if (typeof direction !== "undefined") {
this.setState({ activeRow: rowId });
console.log("Active Row", rowId);
}
}
renderItem = ({ item, index }) => (
<Swipeout
style={styles.SwipeBG}
right={this.swipeBtns}
close={this.state.activeRow !== index}
rowID={index}
sectionId={1}
autoClose={true}
// onOpen = {(secId, rowId, direction) => this.onSwipeOpen(rowId, direction)}
>
<TouchableOpacity
style={styles.item}
activeOpacity={0.4}
onPress={() => {
this.clickedItemText(item);
}}
>
{/* //onPress={this.viewNote(item)} >
> */}
<Text>Id : {item.id}</Text>
<Text>Inventory : {item.inventory}</Text>
<Text>SensorType : {item.sensorType}</Text>
<Text>TypeName : {item.typeName}</Text>
</TouchableOpacity>
</Swipeout>
);
// viewNote =(item) => {
// this.props.navigator.push({
// title: 'The Note',
// component: this.ViewNote,
// passProps: {
// noteText: item,
// noteId: this.noteId(item),
// }
// });
// console.log("View Note Success");
// }
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "86%",
backgroundColor: "#CED0CE"
}}
/>
);
};
render() {
const { loading, AbcSdata } = this.state;
const state = this.state;
return (
<ScrollView>
<View style={styles.container1}>
<Button
full
rounded
style={{ fontSize: 20, color: "green" }}
styleDisabled={{ color: "red" }}
onPress={() => this.onClickListener("tag")}
title="Add Sensors"
>
Add Sensors
</Button>
</View>
<View style={styles.container1}>
{this.state.loading ? (
<ActivityIndicator size="large" />
) : (
<FlatList
style={styles.ListDATA}
data={AbcSdata}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
extraData={this.state.activeRow}
ItemSeparatorComponent={this.renderSeparator}
/>
)}
</View>
<View>
<Text
style={{ alignSelf: "center", fontWeight: "bold", color: "black" }}
>
Inventory Details
</Text>
<Table
borderStyle={{
borderWidth: 2,
borderColor: "#c8e1ff",
padding: 10,
paddingBottom: 10
}}
>
<Rows data={state.tableData} textStyle={styles.text} />
</Table>
</View>
</ScrollView>
);
}
}
export default (OpenApplianceIssue = createStackNavigator({
Item007: { screen: OpenApplianceIssue }
}));
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#ecf0f1",
padding: 8
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: "bold",
textAlign: "center"
},
SwipeBG: {
backgroundColor: "#ffffff",
marginLeft: 7,
marginTop: 3
},
ListDATA: {
backgroundColor: "#ffffff",
marginLeft: 5,
marginTop: 3
}
});
Thanks

react-native-swiper button is not work properly

Issue
The blue active button below is not updated when the react-native-swiper moves as shown below.
For swiper I'm creating a view using the map() function.
Note that passing the key (index) to the child view component does not update the blue button.
If I hardcode the view without using the map() function in swiper, the button will work.
What's the problem?
References Photo
My Code
import React from 'react';
import { View, Platfrom, Text, StyleSheet, AsyncStorage, TouchableOpacity, Image, FlatList, ScrollView } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { connect } from 'react-redux';
import moment from 'moment';
import Swiper from 'react-native-swiper';
import * as settings from '../../config/settings';
const styles = StyleSheet.create({
headerRight: {
padding: 10
},
body_txt: {
marginTop: 5,
padding: 8,
borderWidth: 1,
borderColor: '#EAEAEA',
},
slidmain: {
borderColor: '#EAEAEA',
borderWidth: 1,
},
slide1: {
width: '100%',
height: 300,
},
main: {
flex: 1,
backgroundColor: '#FFFFFF',
padding: 10,
},
image: {
height: 100,
width: '98%',
marginBottom: 70,
marginLeft: '1%',
resizeMode: 'contain',
}
});
class RepairInquiryDetailScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
created_date: '',
photos: [],
key: 0,
}
}
static navigationOptions = ({ navigation }) => ({
title: '수선 문의서',
headerStyle: {
backgroundColor: '#fff',
borderBottomWidth: 0,
elevation: 0,
},
headerTitleStyle: {
color: '#000',
fontSize: 20,
textAlign: 'center',
alignSelf: 'center',
},
headerRight: <Icon name="bars" size={30} color="#333" onPress={() => navigation.navigate('DrawerOpen')} style={styles.headerRight} />
})
RepairInquiryDetailService = async () => {
let user_info = await AsyncStorage.getItem('user_info');
user_token = JSON.parse(user_info).key;
let inquiry_id = this.props.navigation.state.params.id
const api_uri = settings.base_uri + 'inquiry/' + inquiry_id + '/'
fetch(api_uri, {
method: 'GET',
headers: {
'Authorization': 'Token ' + user_token,
}
})
.then(res => res.json())
.then(res => {
let repair_type_tmp = ""
for (i = 0; i < res.repair_type.length; i++) {
if (i == 0) {
repair_type_tmp += res.repair_type[i].type;
} else {
repair_type_tmp += ", " + res.repair_type[i].type;
}
}
let photos_tmp = [];
for (i = 0; i < res.photos.length; i++) {
photos_tmp[i] = res.photos[i].thumbnail;
}
let logistics_tmp = "";
if (res.logistics == "delivery") {
logistics_tmp = "택배";
} else if (res.logistics == "quick") {
logistics_tmp = "퀵";
} else if (res.logistics == "direct") {
logistics_tmp = "방문";
} else {
logistics_tmp = res.logistics;
}
this.setState({
product_type: res.product_type.type,
repair_type: repair_type_tmp,
model: res.model,
content: res.content,
logistics: logistics_tmp,
created_date: res.created_date,
direct_partner: res.direct_partner,
photos: photos_tmp,
})
console.log(this.state.photos)
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.RepairInquiryDetailService();
}
render() {
const parsedDate = moment(this.state.created_date).format("YYYY.MM.DD")
return (
<ScrollView style={styles.main}>
<Swiper
style={styles.slidmain}
height={300}
showsButtons={false}
loop={false}
>
{this.state.photos.map((item, key) => {
console.log(item, key);
return (
<Slide uri={item} key={key} i={key}/>
);
})}
</Swiper>
<View style={styles.body_txt}>
<Text>제품 카테고리: {this.state.product_type}</Text>
<Text>수선 카테고리: {this.state.repair_type}</Text>
<Text>모델명: {this.state.model}</Text>
<Text>배송유형: {this.state.logistics}</Text>
<Text>작성일: {parsedDate}</Text>
<Text>문의 상세내용: {this.state.content}</Text>
</View>
</ScrollView>
)
}
}
const Slide = props => {
console.log('uri and key: ', props.uri, props.i);
return (
<View style={styles.slide1} key={props.i}>
<Image
source={{ uri: props.uri }}
style={styles.slide1}
/>
</View>
);
}
const mapStateToProps = state => ({
isLoggedIn: state.loginReducer.isLoggedIn
})
const RepairInquiryDetail = connect(mapStateToProps, null)(RepairInquiryDetailScreen);
export default RepairInquiryDetail;
Thanks!
A suggested fix to this problem, found here, is to remove the style prop from your Swiper component.
To get your desired border you could wrap your swiper in a parent view. Hope this helps.

Categories

Resources