TaikiTkwkbysh
@TaikiTkwkbysh (WAKA Engineer)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【React/Next.js】レスポンスを受け取るとStateが初期値に戻ってしまう。

解決したいこと

React/Next.jsを使用し、webサービスを作成しています。
バックエンドのSpring bootにリクエストを送り、レスポンスを受け取った後にsetStateを更新し、画面上の値を更新したいのですが、一瞬だけ更新された後、その後に初期値に戻ってしまいます。

解決方法を教えて頂きたいです。

ソース(必要なところを抜粋して記載します)

React/Next.js


import { useEffect, useState } from "react";
import { useMethodContext } from "../context/MethodContext";
import { methodType } from "../type/methodType";
import { Button } from "../styled-components/button";
import { useFormsContext } from "../context/FormContext";
import Cookie from "js-cookie";

const Edit = () => {

    const { states, setStates } = useFormsContext();

    const {language, methodName, type, description, keyword1, keyword2, keyword3,} = states;

    const{setLanguage, setMethodName, setType, setDescription, setKeyword1, setKeyword2, setKeyword3,} = setStates;
    
    const { method, setMethod } = useMethodContext();

    const [ isStatus, setIsStatus ] = useState(false);

    useEffect(() => {
        let saveMethod: string = localStorage.getItem("method")!;
        setMethod(JSON.parse(saveMethod));
        setIsStatus(false);
    }, [])

    const edit =  () => {

        const id = method.id;

        const request: methodType = {
            id,
            language,
            methodName,
            type,
            description,
            keyword1,
            keyword2,
            keyword3,
        };

        const xsrf = Cookie.get('XSRF-TOKEN')!;

        const requestOptions = {
            method: "POST",
            headers: { 
                "Content-Type": "application/json",
                'X-XSRF-TOKEN': xsrf
            },
            body: JSON.stringify(request),
        };

        fetch("http://localhost:8080/edit", requestOptions)
        .then((res) => res.json())
        .then((data) => setMethod(data));
        setIsStatus(true);
    }


    return (
        <div>
            <div>
                <h2>BEFORE</h2>
                                  {  //★  }
                <ul>
                    <li>{method.language}</li>
                    <li>{method.methodName}</li>
                    <li>{method.type}</li>
                    <li>{method.description}</li>
                    <li>{method.keyword1}</li>
                    <li>{method.keyword2}</li>
                    <li>{method.keyword3}</li>
                </ul>
            </div>
            <div>
                <h2>AFTER</h2>
                {
                    isStatus&&(<h2>変更が完了しました。</h2>) // ★
                }
                <form onSubmit={edit}>
                    { // ・・・・・Form中身  }
                    <input type="submit" value="Submit"/>
                </form>
            </div>
        </div>
    )
}

export default Edit;

FormのonSubmitを実行すると、Postリクエストを送信し、
レスポンスで返ってきた値をsetState(setMethod)に格納し、その後setIsStatusにfalseを格納する。

結果、ulリストと「変更が完了しました。」を更新・表示させるようにしたい。

SpringBoot

Controller

package dev.itboot.mb.Controller;

import java.util.List;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import dev.itboot.mb.Model.Method;
import dev.itboot.mb.Service.MethodService;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RestController
@CrossOrigin(origins="*")
public class MethodController {
	
	private final MethodService methodService;
	
	@PostMapping("/edit")
	@ResponseBody
	public Method edit(@RequestBody Method method) {
		methodService.edit(method);
		return methodService.selectById(method.getId());
	}
}

Service


package dev.itboot.mb.Service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import dev.itboot.mb.Mapper.MethodMapper;
import dev.itboot.mb.Model.Method;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
@Transactional
public class MethodService {
	
	private final MethodMapper mapper;
	
	public int edit(Method method) {
		return mapper.edit(method);
	}
}

Mapper

package dev.itboot.mb.Mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import dev.itboot.mb.Model.Method;

@Mapper
public interface MethodMapper {
	
	/* 編集・修正 */
	int edit(Method method);
	
}

0

2Answer

let saveMethod: string = localStorage.getItem("method")!;

ここですかね、localStorageに値をsetしていないので、何もない値で再初期化されている気がします。

1Like

Comments

  1. @TaikiTkwkbysh

    Questioner

    @nayuta9999様

    この度はお忙しい中ご連絡を頂き、誠にありがとうございます。
    記載したコードがわかりづらく、大変申し訳ございません。
    ご指摘頂いた箇所なのですが、こちらは別画面から画面遷移する際にローカルストレージに設定し、
    今回記載したソースの画面に遷移するときに、遷移元でローカルストレージに設定した値を取得するというロジックがございます。

    遷移元画面のソースも記載するべきでした。
    貴重なお時間をいただき、誠にありがとうございました。
    まだまだReactは初心者の身ですので、また機会がございましたら何卒ご教示のほど、宜しくお願い致します。
                <form onSubmit={edit}>
                    { // ・・・・・Form中身  }
                    <input type="submit" value="Submit"/>
                </form>

formのsubmitが既定のsubmit動作をするので,強制的にリロードされています.
デフォルトイベントをキャンセルするか<button type="button"...onClickで代用してください.

1Like

Comments

  1. @TaikiTkwkbysh

    Questioner

    @Verclene様

    この度はご教示いただき、誠にありがとうございます。
    ご教示頂いたとおり、デフォルトイベントをキャンセル(e.prevalent.default)を追加したところ無事解決致しました。

    貴重なお時間をいただき、誠にありがとうございます。
    また機会がございましたら、何卒ご教示のほど宜しくお願い致します。

Your answer might help someone💌