【发布时间】:2022-01-22 10:10:08
【问题描述】:
我有一个反应应用程序,它利用 fetch 从/向 Rails 后端获取和发布/修补数据。我目前拥有它的方式,我只是将获取请求复制并粘贴到每个子组件中,但这似乎非常不合理。我想知道是否有办法在父组件(我的组件列表)中进行动态编码的获取/发布/补丁请求,而不必在每个需要它的组件中重写获取请求。以下是我正在使用的代码:
第一个子组件从文件 components/scripts/script8/page3.js 获取请求:
state = {
handleclick: {
check_words: null,
x_words: ''
},
text: {}
}
handleClick = (e, letter) => {
if (letter === 'c'){
this.setState({handleclick: {check_words: <Checked />, x_words: ''}})
}
else if (letter === 'x'){
this.setState({handleclick: {check_words : null, x_words: "Go to the next page"}})
}
}
handleScroll=()=>{
window.scroll({top:0, behavior:'smooth'})
}
componentDidMount() {
this.handleScroll()
axios.get("http://localhost:3001/texts")
.then(res => {
const texts = res.data;
for (const txt of texts){
if (txt.sheet === "8"){
this.setState({
text: {...this.state.text, [txt.id_tag]: txt}
})
}
}
})
}
handleChange = (event) => {
this.setState({text: {...this.state.text, [event.target.id]: {value: event.target.value, id_tag: event.target.id}}})
if (event.target.id in this.state.text){
axios.patch(`http://localhost:3001/texts/${this.state.text[event.target.id].id}`, {value: event.target.value, id_tag: event.target.id, sheet: "8"})
}
else {
axios.post("http://localhost:3001/texts", {value: event.target.value, id_tag: event.target.id, sheet: "8" })
}
}
<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>
来自 components/scripts/script3/page4.js 的第二个子组件获取请求:
state = {
text: {}
}
handleScroll=()=>{
window.scroll({top:0,behavior:'smooth'})
}
componentDidMount() {
this.handleScroll()
axios.get("http://localhost:3001/texts")
.then(res => {
const texts = res.data;
for (const txt of texts){
if (txt.sheet === "3"){
this.setState({
text: {...this.state.text, [txt.id_tag]: txt}
})
}
}
})
}
handleChange = (event) => {
this.setState({text: {...this.state.text, [event.target.id]: {value: event.target.value, id_tag: event.target.id}}})
if (event.target.id in this.state.text){
axios.patch(`http://localhost:3001/texts/${this.state.text[event.target.id].id}`, {value: event.target.value, id_tag: event.target.id, sheet: "3"})
}
else {
axios.post("http://localhost:3001/texts", {value: event.target.value, id_tag: event.target.id, sheet: "3" })
}
}
getValue = (id) => {
for (const i in this.state.text){
if (this.state.text[i].id_tag === id){
return this.state.text[i].value;
}
}
return ""
}
请注意,唯一的区别是它是哪张纸。最重要的是,例如在 script8 中,两个文件可能具有相同的 fetch 函数。
当前我调用子组件的父组件:
class Script8List extends Component {
state = {button_use: {button_back: false, button_forward: true},
component_list: [<Page1 />, <Page2 />, <Page3 />, <Page4 />, <Page5 />, <Page6 />, <Page7 />, <Page8 />, <Page9 />, <Page10 />, <Page11 />, <Page12 />],
pagePos: 0}
handleClick = (letter) => {//This determines which button was pressed
if (letter === 'b'){
this.setState((prevState) => ({pagePos: prevState.pagePos - 1}))
}
else {
this.setState((prevState) => ({pagePos: prevState.pagePos + 1}))
}
}
render() {
return(
<div className="Script8">{this.state.component_list[this.state.pagePos]}
<div id="buttonDiv">
{this.state.pagePos === 0 ? null : <img alt="left arrow back" src={larrow} onClick={() => this.handleClick('b')} className="left arrow button"/>}
{this.state.pagePos === this.state.component_list.length - 1 ? null : <img alt="right arrow forward" src={rarrow} onClick={() => this.handleClick('f')} className="right arrow button"/>}
</div>
<h3 className="page_num">{this.state.pagePos + 1}</h3>
</div>
)
}
}
export default Script8List;
<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>
这就是我希望父组件的样子:
class Script8List extends Component {
state = {button_use: {button_back: false, button_forward: true},
component_list: [<Page1 />, <Page2 />, <Page3 />, <Page4 />, <Page5 />, <Page6 />, <Page7 />, <Page8 />, <Page9 />, <Page10 />, <Page11 />, <Page12 />],
pagePos: 0}
handleClick = (letter) => {//This determines which button was pressed
if (letter === 'b'){
this.setState((prevState) => ({pagePos: prevState.pagePos - 1}))
}
else {
this.setState((prevState) => ({pagePos: prevState.pagePos + 1}))
}
}
handleClick = (e, letter) => {
if (letter === 'c'){
this.setState({handleclick: {check_words: <Checked />, x_words: ''}})
}
else if (letter === 'x'){
this.setState({handleclick: {check_words : null, x_words: "Go to the next page"}})
}
}
handleScroll=()=>{
window.scroll({top:0, behavior:'smooth'})
}
componentDidMount() {
this.handleScroll()
axios.get("http://localhost:3001/texts")
.then(res => {
const texts = res.data;
for (const txt of texts){
if (txt.sheet === {current_sheet}){
this.setState({
text: {...this.state.text, [txt.id_tag]: txt}
})
}
}
})
}
handleChange = (event) => {
this.setState({text: {...this.state.text, [event.target.id]: {value: event.target.value, id_tag: event.target.id}}})
if (event.target.id in this.state.text){
axios.patch(`http://localhost:3001/texts/${this.state.text[event.target.id].id}`, {value: event.target.value, id_tag: event.target.id, sheet: {current_sheet}})
}
else {
axios.post("http://localhost:3001/texts", {value: event.target.value, id_tag: event.target.id, sheet: {current_sheet} })
}
}
render() {
return(
<div className="Script8">{this.state.component_list[this.state.pagePos]}
<div id="buttonDiv">
{this.state.pagePos === 0 ? null : <img alt="left arrow back" src={larrow} onClick={() => this.handleClick('b')} className="left arrow button"/>}
{this.state.pagePos === this.state.component_list.length - 1 ? null : <img alt="right arrow forward" src={rarrow} onClick={() => this.handleClick('f')} className="right arrow button"/>}
</div>
<h3 className="page_num">{this.state.pagePos + 1}</h3>
</div>
)
}
}
export default Script8List;
我唯一的问题是我不知道如何动态地执行此操作,以便我可以实时将信息发送到父组件,同时保持页面不变。部分问题是我会在文本框中发生变化的任何时候进行这些调用,因此我需要知道如何在两者之间进行交流。
【问题讨论】:
-
不清楚您要完成什么。既然您在谈论父/子组件,您能否展示父子组件并准确描述问题出在哪里?您是否只是想为每个组件创建一个可重用的函数(如 useApi 挂钩?)
-
@windowsill 那是我的错,我将编辑主要帖子,以便您更好地理解。
-
所有子组件都对/texts 使用相同的api 调用吗?即使您说您的问题与重复有关,您仍然没有显示任何重复。
-
请更新您的问题以包含重复内容。
-
@windowsill 啊该死的好吧我更新了它以包含这个。
标签: javascript reactjs react-native axios fetch