I am only able to see a part of my app in React Native despite the fact that I have wrapped the app in a ScrollView component.
I have tried a number of solutions but none of them have worked:
Failed attempts:
Setting flexGrow to 1
Setting padding to 10
Setting flex to 1
None of these do anything.
How do you configure ScrollView so that all of its children are visible?
Here is the app:
import { StyleSheet, Text, View, TextInput, Pressable, ScrollView } from 'react-native';
import {useState, useEffect} from 'react'
import axios from 'axios'
import SelectDropdown from 'react-native-select-dropdown'
import { Formik } from 'formik'
export default function App() {
const [price, setPrice] = useState();
const options = ["ARS", "ARD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HRK", "HUF", "INR", "ISK", "JPK", "KRW", "NZD", "PLN", "RON", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "USD"]
const [selected, setSelected] = useState(options[0])
const [amount, setAmount] = useState('')
const [calculatedAmount, setCalculatedAmount] = useState()
useEffect(() => {
axios.get('https://blockchain.info/ticker')
.then(data => {
setPrice(data)
})
}, [])
const fetchData = () => {
axios.get(`https://blockhain.info/tobtc?currency=${selected}&value=${amount}`)
.then(data => {
setCalculatedAmount(data.data)
console.log(calculatedAmount)
})
}
const handleSubmit = (e) => {
e.preventDefault()
fetchData()
}
const handleAmountChange = (e) => {
e.preventDefault()
setAmount(e.target.value)
}
if (!price || price === undefined ) {
return null
}
const Form = ({ onSubmit }) => {
<View>
<Text className="py-10 text-xl">Enter value: <TextInput className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="amount" placeholder="Enter value in selected currency" value={amount} onChange={handleAmountChange} data-cy="amount"></TextInput></Text>
<Text className="text-center"><Pressable className="p-5 mb-2 mr-2 overflow-hidden text-2xl text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white text-black font-bold focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800" id="convert-button" type="submit"><Text>Calculate!</Text></Pressable></Text>
<Text id="#calculatedamount" className="text-xl py-8 bg-gray-100 px-2 font-bold rounded-md" data-cy="submit">Value: {calculatedAmount} BTC</Text>
</View>
}
return (
<ScrollView className=" h-screen bg-blue-100" contentContainerStyle={{ flexGrow: 1}}>
<View className="py-10">
<Text className="text-xl text-center m-auto text-black font-bold">Current Prices</Text>
</View>
<View className="md:flex justify-around h-full">
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">(£) {price.data.GBP.symbol} {price.data.GBP.last} BTC</Text>
</View>
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">(€) {price.data.EUR.symbol} {price.data.EUR.last} BTC</Text>
</View>
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">($) {price.data.USD.symbol} {price.data.USD.last} BTC</Text>
</View>
</View>
<View className="h-screen flex ">
<View className="m-auto bg-blue-300 p-20 rounded-md shadow-2xl">
<Text className="text-3xl font-bold py-10">Convert Currency into BTC</Text>
<Text className="text-xl"> Select a currency: <SelectDropdown className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
id='currency'
value={selected}
data-cy="select"
onChange={(e) => setSelected(e.target.value)}>
{options.map((value) => (<Text>
<Text value={value} key={value}>
<Text> {value}</Text>
</Text>
</Text>))}
</SelectDropdown></Text>
<Formik initialValues={{ amount: '' }} onSubmit={handleSubmit}>
{({ handleSubmit }) => <Form onSubmit={handleSubmit} />}
</Formik>
</View>
</View>
</ScrollView>
);
}
ScrollView has two styling props: style and contentContainerStyle.
The style prop is used for the styling of the ScrollView parent
element.
The contentContainerStyle prop is a scrollable container inside the
parent ScrollView
So to set the correct lay-outing for the ScrollView we need update the props: style like this,
< ScrollView style = {
styles.scrollView
} >
//... childrens
<
/ScrollView>
const styles = StyleSheet.create({
scrollView: {
flex: 1,
backgroundColor: 'pink',
marginHorizontal: 20,
}
});
Please refer this blog for more details
Related
I'm having an issue when using redux form with react native, when I toggle the password visibility the password field input is cleared, when I remove redux form things work as expected. Below is the code I'm using, I also tried saving the value to a local state but that doesn't work either.
import React, {useState} from 'react';
import {StatusBar} from 'react-native';
import {Icon, FormControl, Button, HStack, Pressable} from 'native-base';
import {Field, reduxForm} from 'redux-form';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import PropTypes from 'prop-types';
import Input from './Input';
import {withActions} from 'context/ActionsContext';
const LoginForm = props => {
const {handleSubmit, submitting, invalid, toggleCreate, toggleModal} = props;
const [show, setShow] = useState(false);
return (
<>
<StatusBar barStyle="light-content" />
<Field
name="email"
component={field => (
<FormControl isInvalid={field.meta.error} mb="6">
<Input
input={field.input}
key={field.name}
placeholder="Email Address"
type="text"
keyboardType="email-address"
textContentType="emailAddress"
light
/>
<FormControl.ErrorMessage>
{field.meta.error}
</FormControl.ErrorMessage>
</FormControl>
)}
/>
<Field
name="password"
component={field => (
<FormControl isInvalid={field.meta.error} mb="6">
<Input
input={field.input}
key={field.name}
placeholder="Password"
type={show ? 'text' : 'password'}
keyboardType="default"
textContentType="password"
light
rightComponent={
<Pressable onPress={() => setShow(!show)}>
<Icon
as={
<MaterialIcons
name={show ? 'visibility' : 'visibility-off'}
/>
}
size={5}
mr="2"
/>
</Pressable>
}
/>
<FormControl.ErrorMessage>
{field.meta.error}
</FormControl.ErrorMessage>
</FormControl>
)}
/>
<Button
rounded="lg"
mt="3"
colorScheme="red"
_text={{
fontFamily: 'neuzeitBook',
fontSize: 'md',
fontWeight: '700',
}}
isDisabled={submitting || invalid}
onPress={handleSubmit}>
Sign in
</Button>
<Button
rounded="lg"
mt="6"
variant="solidLight"
_text={{
fontFamily: 'neuzeitBook',
fontSize: 'md',
}}
onPress={toggleCreate}>
Create Account
</Button>
<HStack mt="6" justifyContent="center">
<Button
p="3"
color="white"
variant="link"
onPress={toggleModal}
_text={{
fontFamily: 'neuzeitBook',
fontSize: 'md',
fontWeight: 'bold',
color: 'white',
}}>
Reset Password
</Button>
</HStack>
</>
);
};
LoginForm.propTypes = {
handleSubmit: PropTypes.func.isRequired,
placeholder: PropTypes.string,
};
export default reduxForm({
form: 'login',
})(withActions(LoginForm));
I tried removing redux form and it works as expected.
I have an issue. I have a dating similar to tinder and when there is no more profiles the following card is displayed :
enter image description here
My problem is that when I open the app, this card is rendered for 2 of 3 seconds before the profiles. I tried to have a loading symbol, when fetchcards is done, this problem persists :
The following is my code :
const fetchCards = async () => {
setloading(true);
const passes = await getDocs(collection(db, "user", user.uid, "passes")).then(
(snapshot) => snapshot.docs.map((doc) => doc.id)
);
const swipes = await getDocs(collection(db, "user", user.uid, "swipes")).then(
(snapshot) => snapshot.docs.map((doc) => doc.id)
);
const passedUserIds = passes.length > 0 ? passes : ["test"];
const swipedUserIds = swipes.length > 0 ? swipes : ["test"];
const sex = await getDocs(collection(db, "femmes")).then(
(snapshot) => snapshot.docs.map((doc) => doc.id)
);
const sexUserIds = sex.length > 0 ? sex : ["test"];
//console.log('sex : ' + sex );
// console.log('sexUserIds : ' + sexUserIds );
// console.log('user.uid : ' + user.uid );
artie = sexUserIds.includes(user.uid);
//console.log(' artie : ' + artie );
let difference = sexUserIds.filter(x => !passedUserIds.includes(x));
const difference2 = difference.filter(x => !swipedUserIds.includes(x));
//console.log(' similitude entre sexUserIds et swipedUserIds : ' + sexUserIds.filter(e => swipedUserIds.includes(e)));
//console.log(' similitude final : ' + sexUserIds.filter(e => passedUserIds.includes(e)));
if (artie == true) {
// femmme
unsub = onSnapshot(query(collection(db, "user"), where("id", "not-in", [...passedUserIds, ...swipedUserIds, ...sexUserIds])
),
(snapshot) => {
setProfiles(
snapshot.docs
.filter((doc) => doc.id !== user.uid)
.map((doc) => ({
id: doc.id,
...doc.data(),
}))
);
});
} else {
// homme
unsub = onSnapshot(query(collection(db, "user"), where("id", "in", [...difference2])
),
(snapshot) => {
setProfiles(
snapshot.docs
.filter((doc) => doc.id !== user.uid)
.map((doc) => ({
id: doc.id,
...doc.data(),
}))
);
});
}
setloading(false);
};
fetchCards();
return unsub;
}, [db]);
return (
<SafeAreaView style={tw("flex-1 top-10")}>
{/*Header*/}
<View style={tw("flex-row justify-between items-center ")}>
<TouchableOpacity onPress={logout}>
<Image style={tw("relative rounded-full h-16 w-16 mr-4")} source={{ uri: profilepic }}/>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate("Modal")}>
<Image style={tw("h-14 w-14")} source={require("../logo.png")}/>
</TouchableOpacity>
<Button onPress={() => navigation.navigate("Chat")} title="Messages" color="#e71e24" style={tw("absolute left-7 top-3")}/>
</View>
{/*End of Header*/}
{/* Cards */}
<View style={tw("flex-1 -mt-6")}>
<Swiper
ref={swipeRef}
containerStyle={{ backgroundColor: "transparent" }}
cards={profiles}
stackSize={5}
cardIndex={0}
animateCardOpacity
verticalSwipe={true}
onSwipedLeft={(cardIndex) => {
console.log('SWIPE PASS');
swipeLeft(cardIndex);
}}
onSwipedRight={(cardIndex) => {
console.log('SWIPE MATCH');
swipeRight(cardIndex);
}}
onSwipedTop={(cardIndex) => {
console.log('FLAG');
swipeTop(cardIndex);
}}
backgroundColor={"#4FD0E9"}
overlayLabels={{
left: {
title: "NOPE",
style: {
label: {
textAlign: "right",
color: "red",
},
},
},
right: {
title: "MATCH",
style: {
label: {
color: "#4DED30",
},
},
},
top: {
title: "FLAG",
style: {
label: {
color: "#4DED30",
},
},
},
}}
renderCard={(card) => card ? (
<View key={card.id} style={tw("relative bg-white h-3/4 rounded-xl")}>
<Image
style={tw("absolute top-0 h-full w-full rounded-xl")}
source={{ uri: card.photoURL}}
/>
<View style={[tw("absolute bottom-0 bg-white w-full flex-row justify-between items-center h-20 px-6 py-2 rounded-b-xl"), styles.cardShadow,]}>
<View>
<Text style={tw("text-xl font-bold")}>
{card.displayName}
</Text>
<Text>{card.job}</Text>
</View>
<Text style={tw("text-2xl font-bold")}> {card.age}</Text>
</View>
</View>
) : (
<View
style={[
tw("relative bg-white h-3/4 rounded-xl justify-center items-center"
),
styles.cardShadow,
]}
>
<Text style={tw("font-bold pb-5")}>Plus de profils</Text>
<Image
style={tw('h-20 w-20 rounded-full')}
source={{uri: "https://links.papareact.com/6gb" }}
/>
</View>
)}
/>
<View style={styles.row}>
<View>
{getBannerAd()}
</View>
<StatusBar style="auto" />
</View>
</View>
<View style={tw("flex flex-row justify-evenly bottom-10")}>
<TouchableOpacity
onPress={()=> swipeRef.current.swipeLeft()}
style={tw("items-center justify-center rounded-full w-16 h-16 bg-red-200")}>
<Entypo name="cross" size={24} color="red"/>
</TouchableOpacity>
<TouchableOpacity
onPress={()=> swipeRef.current.swipeTop()}
style={tw("items-center justify-center rounded-full w-16 h-16 bg-purple-200")}>
<Entypo name="warning" size={24} color="red"/>
</TouchableOpacity>
<TouchableOpacity
onPress={()=> swipeRef.current.swipeRight()}
style={tw("items-center justify-center rounded-full w-16 h-16 bg-green-200")}>
<AntDesign name="heart" size={24} color="green"/>
</TouchableOpacity>
</View>
</SafeAreaView>
);
Since you are using a loading state, you could use an additional conditional in your render function and wait until the date is fetched before you decide which cards to show (the fetched cards or the “no cards” screen).
renderCard={(card) => {
if(isLoading) {
// return whatever
} else if(card){
return <View key={card.id} style={tw("relative bg-white h-3/4 rounded-xl")}>
<Image
style={tw("absolute top-0 h-full w-full rounded-xl")}
source={{ uri: card.photoURL}}
/>
<View style={[tw("absolute bottom-0 bg-white w-full flex-row justify-between items-center h-20 px-6 py-2 rounded-b-xl"), styles.cardShadow,]}>
<View>
<Text style={tw("text-xl font-bold")}>
{card.displayName}
</Text>
<Text>{card.job}</Text>
</View>
<Text style={tw("text-2xl font-bold")}> {card.age}</Text>
</View>
</View>
} else {
return <View
style={[
tw("relative bg-white h-3/4 rounded-xl justify-center items-center"
),
styles.cardShadow,
]}
>
<Text style={tw("font-bold pb-5")}>Plus de profils</Text>
<Image
style={tw('h-20 w-20 rounded-full')}
source={{uri: "https://links.papareact.com/6gb" }}
/>
</View>
)}
}
}
It might be suitable to just return null.
I've got an array of AsyncSelect components.
How to set borderColor for one AsyncSelect of array?
It try to set for all row this borderColor when some condition.
class ConditionBox extends Component {
render() {
return (
<div>
{cardsData.map(item => {
return (<ConditionItem {...item} />);
})}
</div>
)
}
}
class ConditionItem extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div style={{display: 'block'}}>
<div style={{display: 'inline-block', width: '250px', marginRight: '1em'}}>
<Label
htmlFor="date-to"
label="Task Owner:"
/>
<AsyncSelect
className="async-select-with-callback"
classNamePrefix="react-select"
getOptionValue={getOptionValue}
onChange={onOwnerFieldChange}
defaultOptions
index={this.props.index}
loadOptions={loadOptions}
isSearchable={true}
defaultValue={getSelectedOption(this.props.index, 'owner')}
placeholder="Choose Task"
/>
</div>
<div style={{display: 'inline-block', width: '150px', marginRight: '1em'}}>
<Label
htmlFor="date-to"
label="Type:"
/>
<AsyncSelect
className="async-select-with-callback"
classNamePrefix="react-select"
getOptionValue={getOptionValue}
onChange={onOperationTypeFieldChange}
index={this.props.index}
defaultOptions={[
{
label:
'Serial',
value: 'SL',
},
{
label:
'Parallel',
value: 'PR',
},
]}
isSearchable={false}
placeholder="Choose Type"
defaultValue={getSelectedOption(this.props.index, 'condition')}
/>
</div>
<div style={{display: 'inline-block', width: '250px', marginRight: '1em'}}>
<Label
htmlFor="date-to"
label="Task Owned:"
/>
<AsyncSelect
className="async-select-with-callback"
classNamePrefix="react-select"
getOptionValue={getOptionValue}
onChange={onOwnedFieldChange}
defaultOptions
loadOptions={loadOptions}
index={this.props.index}
isSearchable={true}
placeholder="Choose Task"
defaultValue={getSelectedOption(this.props.index, 'owned')}
/>
</div>
<div style={{display: 'inline-block'}}>
<Button onClick={() => removeCondition(this.props)}>Remove</Button>
</div>
</div>
)
}
}
function rebuildCondtions() {
cardsData.push({index: cardsData.length, owner: "", condition: "", owned: ""});
ReactDOM.render(<ConditionBox/>, document.getElementById('conditionbox'));
}
export default () => {
return (
<div>
<h3>Triangu Task Order</h3>
<div style={{width: '90%', marginLeft: '7%'}}>
<div style={{display: 'inline'}}>
<div id="conditionbox"/>
</div>
<div style={{paddingTop: '15px'}}>
<Button onClick={rebuildCondtions}>Add</Button>
</div>
</div>
</div>
);
};
Here's an example, and don't forget about keys when you render arrays.
class ConditionBox extends Component {
render() {
return (
<div>
{cardsData.map(item => {
return (<ConditionItem {...item} key={item.id} isHighlighted={isItemHighlighted(item)}/>);
})}
</div>
)
}
}
class ConditionItem extends Component {
constructor(props) {
super(props);
}
render() {
const borderColor = this.props.isHighlighted ? 'red' : 'black';
return (
<div style={{display: 'block', borderColor }}>
/*...all other code, you can use 'borderColor' somewhere else as well...*/
</div>
}
I'm trying to fetch the date and format it using moment , the solution i found is to store the date in a variable , and i've been having a problem with that followed this awnser since i hade the same problem . although i managed to get rid of the unexpected token error but i got my self in another one . MY FLAT LIST IS NOT SHOWING ANYMORE.
here is my code :
import React, { Component } from "react";
import {View,StyleSheet,FlatList,ListView} from "react-native";
import {Container, Header, Left, Body, Right, Title, Subtitle,Icon ,Content, Footer, FooterTab, Button, Text,Badge , List , ListItem} from 'native-base'
import Icon0 from 'react-native-vector-icons/MaterialCommunityIcons'
import Icon1 from 'react-native-vector-icons/FontAwesome'
import CountDown from 'react-native-countdown-component';
import moment from 'moment';
class Consulter extends Component{
state ={
data:[]
}
fetchData= async()=>{
const response = await fetch('http://192.168.1.4:3000/rendezvous/1');
const rendezvous =await response.json();
this.setState({data:rendezvous});
}
componentDidMount() {
this.fetchData();
}
render() {
const today = this.state.currentDate;
const day = moment(today).format("dddd");
const date = moment(today).format("MMMM D, YYYY");
return (
<Container>
<Content >
<View style ={{ flex:1}}>
<FlatList
data={this.state.data}
keyExtractor={(item,index) => index.toString()}
renderItem={({item}) =>
{let dates=item.date;
<View style={{backgroundColor:'#e6e6e6',padding:10,margin:10}}>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon0 active name="doctor" />
</Button>
</Left>
<Body>
<Text>Nom du Docteur : Dr. {item.nom}</Text>
</Body>
</ListItem>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon1 active name="calendar" />
</Button>
</Left>
<Body>
<Text>Date du rendez-vous :</Text>
<Text> dates </Text>
</Body>
</ListItem>
<ListItem icon>
<Left>
<Button style={{ backgroundColor: "white" }}>
<Icon1 active name="calendar"/>
</Button>
</Left>
<Body>
<CountDown
until= {item.date}
timetoShow={('H', 'M', 'S')}
onFinish={() => alert('finished')}
onPress={() => alert('hello')}
size={10}
/>
</Body>
</ListItem>
</View>
}}
/>
</View>
</Content>
</Container>
);
}
}
export default Consulter;
const styles =StyleSheet.create({
container : {
flex: 1,
}
})
Ps : there is no compilation errors.
you need to use a return statement, like that:
<FlatList
data={this.state.data}
keyExtractor={(item,index) => index.toString()}
renderItem={({item}) =>
{let dates=item.date;
return(
<View style={{backgroundColor:'#e6e6e6',padding:10,margin:10}}>
<ListItem icon>
...
);
renderItem expects you to return some jsx ... and you didn't
Try this:
<FlatList
data={this.state.data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item: { date } }) => (<View>// the rest of your jsx</View>)}
/>
I am using react-slick to create a carousel in my project.
I've read through the documents and tried different things but could not find a way to customize it exactly the way I need... Does anyone knows if there a way to have the nextArrow show on/in front of the image and not on its right?
See image below for desired result:
image
Thanks for your help!
I faced the same problem and have been trying to search for the solutions by following this CustomArrows documentation and some other suggestions but none of them working as what I wanted to (use different icons for the arrow and display the arrow on top of the slides). Then I tried to follow this previousNextMethods documentation, and try to adjust it from there.
index.js
renderArrows = () => {
return (
<div className="slider-arrow">
<ButtonBase
className="arrow-btn prev"
onClick={() => this.slider.slickPrev()}
>
<ArrowLeft />
</ButtonBase>
<ButtonBase
className="arrow-btn next"
onClick={() => this.slider.slickNext()}
>
<ArrowRight />
</ButtonBase>
</div>
);
};
render() {
return (
<div className="App">
<div style={{ position: "relative", marginTop: "2rem" }}>
{this.renderArrows()}
<Slider
ref={c => (this.slider = c)}
dots={true}
arrows={false}
centerMode={true}
slidesToShow={2}
>
<div>
<img src="http://placekitten.com/g/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/g/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/400/200" alt="cat" />
</div>
</Slider>
</div>
</div>
);
}
style.css
.App {
font-family: sans-serif;
}
.slider-arrow {
position: absolute;
z-index: 1;
height: 100%;
width: 100%;
}
.arrow-btn {
top: 45%;
}
.next {
float: right;
}
I hope this will help. codesandbox
I tend to disable the arrows and build them myself.
Create a reference
const slider = React.useRef(null);
Attach to the slider
<Slider ref={slider} {...settings}>
Add your buttons wherever you want
<button onClick={() => slider?.current?.slickPrev()}>Prev</button>
<button onClick={() => slider?.current?.slickNext()}>Next</button>
See official documentation
https://react-slick.neostack.com/docs/example/custom-arrows/
https://react-slick.neostack.com/docs/example/previous-next-methods
Code from there:
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
OR
import React, { Component } from "react";
import Slider from "react-slick";
export default class PreviousNextMethods extends Component {
constructor(props) {
super(props);
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
}
next() {
this.slider.slickNext();
}
previous() {
this.slider.slickPrev();
}
render() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
return (
<div>
<h2>Previous and Next methods</h2>
<Slider ref={c => (this.slider = c)} {...settings}>
<div key={1}>
<h3>1</h3>
</div>
<div key={2}>
<h3>2</h3>
</div>
<div key={3}>
<h3>3</h3>
</div>
<div key={4}>
<h3>4</h3>
</div>
<div key={5}>
<h3>5</h3>
</div>
<div key={6}>
<h3>6</h3>
</div>
</Slider>
<div style={{ textAlign: "center" }}>
<button className="button" onClick={this.previous}>
Previous
</button>
<button className="button" onClick={this.next}>
Next
</button>
</div>
</div>
);
}
}
You can try this way
render() {
const ArrowLeft = (props) => (
<button
{...props}
className={'prev'}/>
);
const ArrowRight = (props) => (
<button
{...props}
className={'next'}/>
);
const settings = {
arrows: true,
prevArrow: <ArrowLeft />,
nextArrow: <ArrowRight />,
};
return (
<Slider {...settings}>
{/* items... */}
</Slider>
)
}
If anyone tries to achieve the same result, the way to do it is with some css:
.slick-next {
right: 25px;
}
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
Check the React-slick Custom Next & Prev buttons here : https://react-slick.neostack.com/docs/example/custom-arrows
Add custom css style
.slick-next {
background: url('./images/next.png') center center no-repeat!important;
&::before {
display: none;
}
}
.slick-prev {
background: url('./images/back.png') center center no-repeat!important;
&::before {
display: none;
}
}
You can build your own arrows and it is mentioned in their documentation like everyone pointed out above.
But if you want to change the images (which mostly would be the case) so what I did was just added 2 lines of code for slider .slick-next:before & .slick-prev:beforeand replaced the content with images. With this you dont need to handle disabling the arrows on last item (which is default). Using the code below just changes your arrows and rest of the behavior remains the same.
See the code below
.some_class .slick-slider {
button.slick-next:before {
content: url("your_image_here.svg");
}
button.slick-prev:before {
content: url("your_image_here.svg");
}
}
Remember that it is required to add onClick prop to your buttons:
const SlickArrow = ({onClick}: props) => (
<button onClick={onClick}><Icon.Arrow /></button>
);
I started with the answer from Oleg above and changed it just a bit to use FontAwesome icons. This method works well to keeps the extra properties from being sent to the FontAwesome components that result in errors such as "React does not recognize the currentSlide prop on a DOM element". Thanks to Oleg for the pattern.
import React from 'react';
import Slider from 'react-slick';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
const SomeComponent: React.FC = (): JSX.Element => {
const NextArrow = (props: any) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: 'block' }}
onClick={onClick}
>
<FontAwesomeIcon icon="fa-solid fa-chevron-right" />
</div>
);
};
const PrevArrow = (props: any) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: 'block' }}
onClick={onClick}
>
<FontAwesomeIcon icon="fa-solid fa-chevron-left" />
</div>
);
};
const settings = {
// other settings here ...
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
// more settings here ...
};
return (
<Slider {...settings}>
{/* inner stuff here */}
</Slider>
);
};
This example replaces the default arrow by another icon
import Slider from "react-slick";
import './Example2.css'
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { FaBeer } from 'react-icons/fa'
function SampleNextArrow(props: any) {
const { className, style, onClick } = props;
return (
<div
className={className}
onClick={onClick}
><FaBeer style={{ ...style, color: "red", fontSize: "30px" }} /></div>
);
}
function SamplePrevArrow(props: any) {
const { className, style, onClick } = props;
return (
<div
className={className}
onClick={onClick}
><FaBeer style={{ ...style, color: "red", fontSize: "30px" }} /></div>
);
}
const Example2 = () => {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div className="wrapper">
<h1>example 2</h1>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
export default Example2;
and the css
.slick-arrow.slick-next:before {
content: "";
}
.slick-arrow.slick-prev:before {
content: "";
}
import React from 'react';
import Slider from 'react-slick';
import prevArrow from './prev-arrow.svg';
import nextArrow from './next-arrow.svg';
const SliderCarousel = () => {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
prevArrow: <CustomPrevArrow />,
nextArrow: <CustomNextArrow />
};
return (
<Slider {...settings}>
{/* Slides */}
</Slider>
);
};
const CustomPrevArrow = (props) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, width: '50px', height: '50px', backgroundImage: `url(${prevArrow})`}}
onClick={onClick}
/>
);
}
const CustomNextArrow = (props) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, width: '50px', height: '50px', backgroundImage: `url(${nextArrow})`}}
onClick={onClick}
/>
);
}
export default SliderCarousel;
You can do like this