使用 redux/toolkit 进行组件间的状态切片
Using redux / toolkit for state slicing between components
我的 SlideShow with Redux 遇到了问题,我是新手。我试图找出连接下拉列表 select 和下一个和上一个按钮的逻辑,以便 redux 跟踪我的状态。
我希望用户能够浏览幻灯片,还能够 select 从下拉列表中选择一张幻灯片。我无法弄清楚我应该做些什么来连接这一切,但我想我很接近......:\
我的幻灯片
const SlideData = [
{
title: "Introduction",
content: "This is some content",
},
{
title: "Slide 2",
content: "This is some content",
},
{
title: "Slide 3",
content: "This is some content",
},
{
title: "Slide 4",
content: "This is some content",
},
];
export default SlideData;
REDUX 文件
import { createSlice, configureStore } from "@reduxjs/toolkit";
import SlideData from "../SlideData";
//SET INITIAL STATE//
const initialSlideState = {
SlideData,
totalSlides: SlideData.length,
currentSlide: 0,
progress: 0,
};
//SET REDUCERS//
const slideSlice = createSlice({
name: "slide",
initialState: initialSlideState,
reducers: {
setCurrentSlide(state, action) {
state.currentSlide = SlideData[action.payload];
},
nextSlide(state) {
if (state.currentSlide < state.totalSlides) {
state.currentSlide++;
}
},
prevSlide(state) {
if (state.currentSlide > 0) {
state.currentSlide--;
}
},
setProgress(state, action) {
state.progress = action.payload;
},
},
});
//CREATE STORE//
const store = configureStore({
reducer: slideSlice.reducer,
});
export const slideActions = slideSlice.actions;
export default store;
幻灯片文件
//IMPORTS//
import React, { useRef } from "react";
import styles from "./Slideshow.module.css";
import Button from "./UI/Button";
import { Slide } from "react-slideshow-image";
import SlideData from "../SlideData";
import { useSelector, useDispatch } from "react-redux";
import { slideActions } from "../store/index";
import "react-slideshow-image/dist/styles.css";
export default function Slideshow() {
const dispatch = useDispatch();
const slideRef = useRef();
const currentSlide = useSelector((state) => state.currentSlide);
const totalSlides = useSelector((state) => state.totalSlides);
//SET CURRENT SLIDE
const setCurrentSlideHandler = (index) => {
dispatch(slideActions.setCurrentSlide(index));
};
//NEXT SLIDE
const nextSlideHandler = () => {
dispatch(slideActions.nextSlide());
dispatch(slideActions.setProgress((currentSlide / totalSlides) * 100));
slideRef.current.goNext();
};
//PREVIOUS SLIDE
const prevSlideHandler = () => {
dispatch(slideActions.prevSlide());
dispatch(slideActions.setProgress((currentSlide / totalSlides) * 100));
slideRef.current.goBack();
};
//GO TO SLIDE (DROPDOWN)<<--feel like i'm close here?
const goto = ({ target }) => {
console.log("Before: " + currentSlide);
let info = parseInt(target.value, 10);
console.log(info);
setCurrentSlideHandler(info);
slideRef.current.goTo(currentSlide);
console.log("after: " + currentSlide);
};
//SLIDESHOW PROPS//
const properties = {
transitionDuration: 200,
autoplay: false,
arrows: false,
};
//MAP DATA FOR DROPDOWN//
const options = SlideData.map((item, index) => (
<option key={index} value={index}>
{item.title}
</option>
));
return (
<div className={styles.container}>
<Slide ref={slideRef} {...properties}>
{SlideData.map((item, index) => (
<div key={index} className={styles.slide}>
<h2>{item.title}</h2>
<p>{item.content}</p>
</div>
))}
</Slide>
<div>
<Button type="button" onClick={prevSlideHandler}>
Back
</Button>
<Button type="button" onClick={nextSlideHandler}>
Next
</Button>
<select className={styles.select} onChange={goto}>
<option>--Select--</option>
{options}
</select>
</div>
</div>
);
}
预览
我认为问题在于,在您的组件中,您既使用库提供的方法,又尝试基于 redux 状态来做事。如果您尝试仅使用 redux 设置幻灯片,那么您想要的是,在按下箭头前进或后退时,将(新的)“currentSlide”(索引)分派给 redux,然后使用 useEffect(())
来监听 currentSlide
选择器的变化。当值发生变化时,您将使用更新后的值通过新索引调用 the libraries method goTo(index)
。
那看起来像:
(免责声明:我正在删除与我要表达的观点无关的内容)
切片
import { createSlice, configureStore } from "@reduxjs/toolkit";
import SlideData from "../SlideData";
//SET INITIAL STATE//
const initialSlideState = {
SlideData,
totalSlides: SlideData.length,
currentSlide: 0,
};
//SET REDUCERS//
const slideSlice = createSlice({
name: "slide",
initialState: initialSlideState,
reducers: {
setCurrentSlide(state, action) {
state.currentSlide = action.payload;
},
nextSlide(state) {
if (state.currentSlide < state.totalSlides) {
state.currentSlide++;
}
},
prevSlide(state) {
if (state.currentSlide > 0) {
state.currentSlide--;
}
},
},
});
组件
//IMPORTS//
import React, { useRef } from "react";
import styles from "./Slideshow.module.css";
import Button from "./UI/Button";
import { Slide } from "react-slideshow-image";
import SlideData from "../SlideData";
import { useSelector, useDispatch } from "react-redux";
import { slideActions } from "../store/index";
import "react-slideshow-image/dist/styles.css";
export default function Slideshow() {
const dispatch = useDispatch();
const slideRef = useRef();
const currentSlide = useSelector((state) => state.currentSlide);
const totalSlides = useSelector((state) => state.totalSlides);
useEffect(() => {
slideRef.current.goTo(currentSlide)
}, currentSlide)
//SET CURRENT SLIDE
const setCurrentSlideHandler = (index) => {
dispatch(slideActions.setCurrentSlide(index));
};
//NEXT SLIDE
const nextSlideHandler = () => {
dispatch(slideActions.nextSlide());
};
//PREVIOUS SLIDE
const prevSlideHandler = () => {
dispatch(slideActions.prevSlide());
};
//GO TO SLIDE (DROPDOWN)<<--feel like i'm close here?
const goto = ({ target }) => {
let info = parseInt(target.value, 10);
setCurrentSlideHandler(info);
};
//SLIDESHOW PROPS//
const properties = {
transitionDuration: 200,
autoplay: false,
arrows: false,
};
//MAP DATA FOR DROPDOWN//
const options = SlideData.map((item, index) => (
<option key={index} value={index}>
{item.title}
</option>
));
return (
<div className={styles.container}>
<Slide ref={slideRef} {...properties}>
{SlideData.map((item, index) => (
<div key={index} className={styles.slide}>
<h2>{item.title}</h2>
<p>{item.content}</p>
</div>
))}
</Slide>
<div>
<Button type="button" onClick={prevSlideHandler}>
Back
</Button>
<Button type="button" onClick={nextSlideHandler}>
Next
</Button>
<select className={styles.select} onChange={goto}>
<option>--Select--</option>
{options}
</select>
</div>
</div>
);
}
根据以上内容,无论您选择哪种方式(前进、后退或明确选择),都会调度适当的操作,并在您所在的状态中更新 currentSlide
(INDEX)获取您的选择器值。当组件发现选择器值已更改时,它将使用该值调用库的 goTo(index)
方法。
我的 SlideShow with Redux 遇到了问题,我是新手。我试图找出连接下拉列表 select 和下一个和上一个按钮的逻辑,以便 redux 跟踪我的状态。 我希望用户能够浏览幻灯片,还能够 select 从下拉列表中选择一张幻灯片。我无法弄清楚我应该做些什么来连接这一切,但我想我很接近......:\
我的幻灯片
const SlideData = [
{
title: "Introduction",
content: "This is some content",
},
{
title: "Slide 2",
content: "This is some content",
},
{
title: "Slide 3",
content: "This is some content",
},
{
title: "Slide 4",
content: "This is some content",
},
];
export default SlideData;
REDUX 文件
import { createSlice, configureStore } from "@reduxjs/toolkit";
import SlideData from "../SlideData";
//SET INITIAL STATE//
const initialSlideState = {
SlideData,
totalSlides: SlideData.length,
currentSlide: 0,
progress: 0,
};
//SET REDUCERS//
const slideSlice = createSlice({
name: "slide",
initialState: initialSlideState,
reducers: {
setCurrentSlide(state, action) {
state.currentSlide = SlideData[action.payload];
},
nextSlide(state) {
if (state.currentSlide < state.totalSlides) {
state.currentSlide++;
}
},
prevSlide(state) {
if (state.currentSlide > 0) {
state.currentSlide--;
}
},
setProgress(state, action) {
state.progress = action.payload;
},
},
});
//CREATE STORE//
const store = configureStore({
reducer: slideSlice.reducer,
});
export const slideActions = slideSlice.actions;
export default store;
幻灯片文件
//IMPORTS//
import React, { useRef } from "react";
import styles from "./Slideshow.module.css";
import Button from "./UI/Button";
import { Slide } from "react-slideshow-image";
import SlideData from "../SlideData";
import { useSelector, useDispatch } from "react-redux";
import { slideActions } from "../store/index";
import "react-slideshow-image/dist/styles.css";
export default function Slideshow() {
const dispatch = useDispatch();
const slideRef = useRef();
const currentSlide = useSelector((state) => state.currentSlide);
const totalSlides = useSelector((state) => state.totalSlides);
//SET CURRENT SLIDE
const setCurrentSlideHandler = (index) => {
dispatch(slideActions.setCurrentSlide(index));
};
//NEXT SLIDE
const nextSlideHandler = () => {
dispatch(slideActions.nextSlide());
dispatch(slideActions.setProgress((currentSlide / totalSlides) * 100));
slideRef.current.goNext();
};
//PREVIOUS SLIDE
const prevSlideHandler = () => {
dispatch(slideActions.prevSlide());
dispatch(slideActions.setProgress((currentSlide / totalSlides) * 100));
slideRef.current.goBack();
};
//GO TO SLIDE (DROPDOWN)<<--feel like i'm close here?
const goto = ({ target }) => {
console.log("Before: " + currentSlide);
let info = parseInt(target.value, 10);
console.log(info);
setCurrentSlideHandler(info);
slideRef.current.goTo(currentSlide);
console.log("after: " + currentSlide);
};
//SLIDESHOW PROPS//
const properties = {
transitionDuration: 200,
autoplay: false,
arrows: false,
};
//MAP DATA FOR DROPDOWN//
const options = SlideData.map((item, index) => (
<option key={index} value={index}>
{item.title}
</option>
));
return (
<div className={styles.container}>
<Slide ref={slideRef} {...properties}>
{SlideData.map((item, index) => (
<div key={index} className={styles.slide}>
<h2>{item.title}</h2>
<p>{item.content}</p>
</div>
))}
</Slide>
<div>
<Button type="button" onClick={prevSlideHandler}>
Back
</Button>
<Button type="button" onClick={nextSlideHandler}>
Next
</Button>
<select className={styles.select} onChange={goto}>
<option>--Select--</option>
{options}
</select>
</div>
</div>
);
}
预览
我认为问题在于,在您的组件中,您既使用库提供的方法,又尝试基于 redux 状态来做事。如果您尝试仅使用 redux 设置幻灯片,那么您想要的是,在按下箭头前进或后退时,将(新的)“currentSlide”(索引)分派给 redux,然后使用 useEffect(())
来监听 currentSlide
选择器的变化。当值发生变化时,您将使用更新后的值通过新索引调用 the libraries method goTo(index)
。
那看起来像: (免责声明:我正在删除与我要表达的观点无关的内容)
切片
import { createSlice, configureStore } from "@reduxjs/toolkit";
import SlideData from "../SlideData";
//SET INITIAL STATE//
const initialSlideState = {
SlideData,
totalSlides: SlideData.length,
currentSlide: 0,
};
//SET REDUCERS//
const slideSlice = createSlice({
name: "slide",
initialState: initialSlideState,
reducers: {
setCurrentSlide(state, action) {
state.currentSlide = action.payload;
},
nextSlide(state) {
if (state.currentSlide < state.totalSlides) {
state.currentSlide++;
}
},
prevSlide(state) {
if (state.currentSlide > 0) {
state.currentSlide--;
}
},
},
});
组件
//IMPORTS//
import React, { useRef } from "react";
import styles from "./Slideshow.module.css";
import Button from "./UI/Button";
import { Slide } from "react-slideshow-image";
import SlideData from "../SlideData";
import { useSelector, useDispatch } from "react-redux";
import { slideActions } from "../store/index";
import "react-slideshow-image/dist/styles.css";
export default function Slideshow() {
const dispatch = useDispatch();
const slideRef = useRef();
const currentSlide = useSelector((state) => state.currentSlide);
const totalSlides = useSelector((state) => state.totalSlides);
useEffect(() => {
slideRef.current.goTo(currentSlide)
}, currentSlide)
//SET CURRENT SLIDE
const setCurrentSlideHandler = (index) => {
dispatch(slideActions.setCurrentSlide(index));
};
//NEXT SLIDE
const nextSlideHandler = () => {
dispatch(slideActions.nextSlide());
};
//PREVIOUS SLIDE
const prevSlideHandler = () => {
dispatch(slideActions.prevSlide());
};
//GO TO SLIDE (DROPDOWN)<<--feel like i'm close here?
const goto = ({ target }) => {
let info = parseInt(target.value, 10);
setCurrentSlideHandler(info);
};
//SLIDESHOW PROPS//
const properties = {
transitionDuration: 200,
autoplay: false,
arrows: false,
};
//MAP DATA FOR DROPDOWN//
const options = SlideData.map((item, index) => (
<option key={index} value={index}>
{item.title}
</option>
));
return (
<div className={styles.container}>
<Slide ref={slideRef} {...properties}>
{SlideData.map((item, index) => (
<div key={index} className={styles.slide}>
<h2>{item.title}</h2>
<p>{item.content}</p>
</div>
))}
</Slide>
<div>
<Button type="button" onClick={prevSlideHandler}>
Back
</Button>
<Button type="button" onClick={nextSlideHandler}>
Next
</Button>
<select className={styles.select} onChange={goto}>
<option>--Select--</option>
{options}
</select>
</div>
</div>
);
}
根据以上内容,无论您选择哪种方式(前进、后退或明确选择),都会调度适当的操作,并在您所在的状态中更新 currentSlide
(INDEX)获取您的选择器值。当组件发现选择器值已更改时,它将使用该值调用库的 goTo(index)
方法。